我有一个 Backbone Collection
,并且我希望它以某种方式响应自己的更新(即添加、删除、重置)。我在各种场景中都遇到过这种情况,但为了讨论起见,假设我正在根据模型 id 计算哈希,以快速比较集合:
var HashedCollection = Backbone.Collection.extend({
updateHash: function() {
// set a simple hash based on model id
this.hash = this.pluck('id').sort().join('|');
}
});
问题是,保持哈希值最新的正确方法是什么?
可能的选项:
为事件设置自监听器:
this.on('add remove reset', this.updateHash, this);
这样做的问题是,某些操作可能会保持沉默,但我仍然想更新哈希值 - 这对于第一次设置来说尤其是一个问题,这在
initialize
中不会发生。因为该集合还没有模型,并且初始重置事件是静默的( relevant code )。另外,这意味着任何其他组件都可以通过传递{ silent: true }
来搞乱集合状态。 .设置
.add
的函数覆盖,.remove
,.reset
,和/或.set
:set: function() { Backbone.Collection.prototype.set.apply(this, arguments); this.updateHash(); } // etc
这里最大的问题是处理单个
add
/set
reset
中的调用与多个调用-reset
来电add
多次,调用set
多次,所以包装set
意味着我们将在重置时为每个项目更新一次哈希值。如果updateHash
比上面的简单示例更昂贵,这可能是一个真正的问题。另一个较小的问题是,我最终得到了很多被重写的函数,导致更多的半样板代码和核心方法中更多潜在的错误。
为了便于讨论,请假设 a) 计算哈希值的成本很高,b) 哈希值被频繁引用。
这里有没有更好的方法来保持集合状态与其模型的最新状态?
最佳答案
我在这一点上可能是错的,但我认为你的“最大问题”(你的话)不是问题。
reset
调用 add
一次。
// from backbone source - Backbone.Collection.reset
reset:
... code above ...
this.add(models, _.extend({silent: true}, options)); // note - silent:true
... code below ...
add
调用 set
一次。
// from backbone source - Backbone.Collection.add
add: function(models, options) {
return this.set(models, _.defaults(options || {}, addOptions));
},
如果您覆盖set
(如您所示)updateHash
将仅在重置时调用一次。
set:function() {
Backbone.Collection.prototype.set.apply(this,arguments);
this.updateHash();
},
这是一个用于演示的 fiddle - http://jsfiddle.net/5ggCd/
您还需要覆盖remove
remove:function() {
Backbone.Collection.prototype.remove.apply(this,arguments);
this.updateHash();
},
关于javascript - 添加/删除/重置时更新 Backbone 集合属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17753561/