我有一个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
多次来电,多次来电{多次{1}},因此包装set
意味着我们将在重置中为每个项目更新一次哈希值。如果set
比上面的简单示例贵,那么这可能是一个真正的问题。另一个较小的问题是我最终得到了很多被覆盖的函数,导致更多的半模板代码和更多核心方法中的错误。
为了便于讨论,请假设a)计算哈希是昂贵的,并且b)经常引用哈希。
这里是否有更好的方法可以使收集状态与其模型保持同步?
答案 0 :(得分:1)
您没有提供任何具体信息,因此很难给出更详细的答案,但总的来说,您正在向后做事。在实际需要之前,不应更新哈希值,
getHash : function(){
return this.pluck('id').sort().join('|');
}
您应该在需要时拨打this.hash
,而不是引用this.getHash()
。然后你的所有同步问题都消失了。
如果你想在事情发生变化时做些事情,那就听一下收藏事件,但是你说的没有说服我,有一个集合需要倾听自己的情况。
答案 1 :(得分:1)
我可能在这方面错了,但我认为你的“最大问题”(你的话)是没有问题的。
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();
},
这是一个演示小提琴 - http://jsfiddle.net/5ggCd/
您还需要覆盖remove
remove:function() {
Backbone.Collection.prototype.remove.apply(this,arguments);
this.updateHash();
},