UNPKG

avalon2

Version:

an elegant efficient express mvvm framework

169 lines (145 loc) 3.6 kB
import { avalon } from '../seed/core' import { runActions, collectDeps } from './transaction' import { createGetter, createSetter } from "../parser/index" export var actionUUID = 1 //需要重构 export function Action(vm, options, callback) { for (var i in options) { if (protectedMenbers[i] !== 1) { this[i] = options[i] } } this.vm = vm this.observers = [] this.callback = callback this.uuid = ++actionUUID this.ids = '' this.mapIDs = {} //这个用于去重 this.isAction = true var expr = this.expr // 缓存取值函数 if (typeof this.getter !== 'function') { this.getter = createGetter(expr, this.type) } // 缓存设值函数(双向数据绑定) if (this.type === 'duplex') { this.setter = createSetter(expr, this.type) } // 缓存表达式旧值 this.oldValue = null // 表达式初始值 & 提取依赖 if (!(this.node)) { this.value = this.get() } } Action.prototype = { getValue() { var scope = this.vm try { return this.getter.call(scope, scope) } catch (e) { avalon.log(this.getter + ' exec error') } }, setValue(value) { var scope = this.vm if (this.setter) { this.setter.call(scope, scope, value) } }, // get --> getValue --> getter get(fn) { var name = 'action track ' + this.type if (this.deep) { avalon.deepCollect = true } var value = collectDeps(this, this.getValue) if (this.deep && avalon.deepCollect) { avalon.deepCollect = false } return value }, /** * 在更新视图前保存原有的value */ beforeUpdate() { var v = this.value return this.oldValue = v && v.$events ? v.$model : v }, update(args, uuid) { var oldVal = this.beforeUpdate() var newVal = this.value = this.get() var callback = this.callback if (callback && this.diff(newVal, oldVal, args)) { callback.call(this.vm, this.value, oldVal, this.expr) } this._isScheduled = false }, schedule() { if (!this._isScheduled) { this._isScheduled = true if (!avalon.uniqActions[this.uuid]) { avalon.uniqActions[this.uuid] = 1 avalon.pendingActions.push(this) } runActions() //这里会还原_isScheduled } }, removeDepends() { var self = this this.observers.forEach(function(depend) { avalon.Array.remove(depend.observers, self) }) }, /** * 比较两个计算值是否,一致,在for, class等能复杂数据类型的指令中,它们会重写diff复法 */ diff(a, b) { return a !== b }, /** * 销毁指令 */ dispose() { this.value = null this.removeDepends() if (this.beforeDispose) { this.beforeDispose() } for (var i in this) { delete this[i] } } } export var protectedMenbers = { vm: 1, callback: 1, observers: 1, oldValue: 1, value: 1, getValue: 1, setValue: 1, get: 1, removeDepends: 1, beforeUpdate: 1, update: 1, //diff //getter //setter //expr //vdom //type: "for" //name: "ms-for" //attrName: ":for" //param: "click" //beforeDispose dispose: 1 }