在添加/删除/重置时更新Backbone Collection属性

时间:2013-07-19 18:58:21

标签: javascript backbone.js backbone-collections

我有一个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)经常引用哈希。

这里是否有更好的方法可以使收集状态与其模型保持同步?

2 个答案:

答案 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();
},