以下是Backbone设置方法的片段:
set: function(key, val, options) {
var attr, attrs, unset, changes, silent, changing, prev, current;
...
options || (options = {});
...
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = options;
for (var i = 0, length = changes.length; i < length; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
// You might be wondering why there's a `while` loop here. Changes can
// be recursively nested within `"change"` events.
if (changing) return this;
if (!silent) {
while (this._pending) {
options = this._pending;
this._pending = false;
this.trigger('change', this, options);
}
}
this._pending = false;
this._changing = false;
return this;
}
虽然评论确实提到了我想知道的while
循环,但我没有看到这个while循环是如何工作的,因为局部变量changing
始终是true
一轮set
。
有人可以向我解释为什么会有一段时间,什么时候会生效?
提前致谢!
答案 0 :(得分:1)
正如评论所说,&#34;更改可以递归嵌套在"change"
个事件中。&#34;
当"change"
事件被触发时,更新或重新设置模型上的某些属性并不是取消注释,而是再次调用set
。 _pending
属性就是为了确保在"change"
上更新的所有属性实际上都已更改。
看起来他们曾经检查过是否有其他更改,以及是否有用于触发just 1 change event的主干。这样做的问题是,如果有更新事件的监听器更新多个属性,则不会调用所有set
函数。有关具体示例,请参阅this unit test。因此while
循环处理1个侦听器多次调用set
的边缘情况,而不是多个侦听器,每次调用set
一次。像上面链接的测试中的这个:
model.on('change:a', function() {
model.set({b: true});
model.set({b: true});
});
如果您对将this._pending
更改为选项的原因感到困惑,请查看this issue&amp; the associated pull request