Commit 23: solved the setter init invoke
-
主要改动:在绑定指令之后就初始化值
-
备注:之前是节点都处理完毕之后,对scope中的值赋值(参见
src/seed.js中的Seed函数),现在是在一个指令绑定完后就初始化(参见src/seed.js中的_bind函数)
Commit 24: better unbind/destroy
- 主要改动:改进了unbind和destroy
- 增加了原型方法
Seed.prototype.destroy -
each指令增加了unbind方法
- 增加了原型方法
Commit 25: fix sd-on
略
Commit 26: computed property progress
-
主要改动:支持计算属性
Directive.prototype.update = function (value) { // computed property if (typeof value === 'function' && !this.fn) { value = value() } // ... }
Commit 27: event delegation in sd-each
-
主要改动:对有
sd-each的节点的事件委托给父节点 -
原理
-
之前的逻辑是,对于以下代码,最后生成的每个
li都绑定了事件<ul sd-show="todos"> <li class="todo" sd-each="todo:todos" sd-class="done:todo.done">...</li> </ul> -
优化之后,对于
sd-each的情况,采用事件委托的方式来处理。 -
思路:在处理
sd-on属性时增加sd-each的情况 -
on指令的结构-
bind:指令第一次绑定到元素时调用在
Seed.prototype._bind函数中,我们可以发现一系列绑定操作后调用了指令的bind方法 -
update:值更新时调用在
Seed.prototype._createBinding函数中,我们可以发现set的时候会调用指令的update方法 -
unbind:移除监听器
-
-
on指令处理过程-
bind
在正常进行绑定后,先调用
bind方法bind: function (handler) { // each的情况 if (this.seed.each) { this.selector = '[' + this.directiveName + '*="' + this.expression + '"]' // 委托给父节点 this.delegator = this.seed.el.parentNode } } -
update
update: function (handler) { // 移除监听器 this.unbind() if (!handler) return var self = this, event = this.arg, selector = this.selector, delegator = this.delegator if (delegator) { // 需要进行事件委托的节点 // for each blocks, delegate for better performance if (!delegator[selector]) { console.log('binding listener') delegator[selector] = function (e) { // 触发事件的对象 var target = delegateCheck(e.target, delegator, selector) if (target) { handler({ el : target, originalEvent : e, directive : self, seed : target.seed }) } } // 在delegator(父节点)上添加监听器 delegator.addEventListener(event, delegator[selector]) } } else { // 普通处理 // a normal handler this.handler = function (e) { handler({ el : e.currentTarget, originalEvent : e, directive : self, seed : self.seed }) } this.el.addEventListener(event, this.handler) } }
-
-
Commit 28: break directives into individual files
把directives中的指令拆成单独的文件了
Commit 29: arrayWatcher
-
主要改动:改进了数组监听
-
原理
-
之前的实现:(Commit 10: kinda working now.)
-
改进之后:
- 仍然是沿袭了之前的思想,即在数组中增加了
pop、push等与Array.prototype中同名的方法。在这些方法中进行了相关扩展 - 改进的是回调函数,即数组变化后(实际上是调用了
pop、push等函数后)应该执行的动作
commit29.png
- 仍然是沿袭了之前的思想,即在数组中增加了
-
代码实现
-
watchArray函数该函数的作用是给
arr增加push/pop/shift/unshift/splice/sort/reverse方法。以
push为例,arr[push]函数的作用是:第一步,调用
Array.prototype中的原生push方法,得到一个新数组result;第二步,执行回调函数。回调函数的参数是 方法名(
push)、原数组的拷贝、resultfunction watchArray (arr, callback) { Object.keys(mutationHandlers).forEach(function (method) { arr[method] = function () { // 调用Array.prototype中的原生push方法 var result = Array.prototype[method].apply(this, arguments) // 执行回调函数 callback({ method: method, args: Array.prototype.slice.call(arguments), result: result }) } }) } -
利用
watchArray监控数组的变化以上我们知道,
watchArray函数可以在数组调用push/pop/shift/unshift/splice/sort/reverse方法时,执行一个回调函数。因此,我们就可以做到每次在数组发生变化时,及时更新DOM在
mutationHandlers中就记录了每个方法执行后该进行哪些后续操作watchArray(collection, function (mutation) { // 调用mutationHandlers中的对应方法 mutationHandlers[mutation.method].call(self, mutation) })
-
-
Commit 30: allow overwritting mutationHandlers
支持重写mutationHandlers











网友评论