Backbone.js:集合的“更改”事件不会触发

我有一个非常简单的集合,但我似乎无法绑定到它的变化事件。 在Chrome的控制台中,我正在运行:

var c = new AwesomeCollection(); c.bind("change", function(){ console.log('Collection has changed.'); }); c.add({testModel: "Test"}); // Shouldn't this trigger the above log statement? 

因为这是难以追查的事情之一,所以我怀疑有谁知道事情的真相(如果真是太棒了!)。 所以,我问了两个问题:

  1. 上述代码是否按预期工作?
  2. 如果是这样,你有什么build议如何追踪这将失败?

谢谢

只有当其中一个集合模型被修改时才会触发change事件。 当模型被添加到集合时, add事件被激发。
请参阅Backbone.js的集合文档 :

您可以绑定“更改”事件,以便在集合中的任何模型被修改时收到通知,侦听“添加”和“删除”事件[…]

要听取何时add修改您的代码

 var c = new AwesomeCollection(); c.bind("add", function(){ console.log('Collection has changed.'); }); c.add({testModel: "Test"}); 

不,只会引发“添加”事件。 如果你这样做,将会引发更改事件:

 var c = new AwesomeCollection(); c.bind("change", function() { console.log('Collection has changed.'); }); var model = new Backbone.Model({testModel: "Test"}); c.add(model); model.set({testModel: "ChangedTest"}); 

如果你想知道什么时候对某个集合进行了重要的处理,那么这些事件就是你可能想听的事情: change add remove reset

就你的例子而言,这就是你的代码的样子:

 var c = new AwesomeCollection(); c.bind('change add remove reset', function(){ console.log('Collection has changed.'); }); 

在大多数情况下可能不需要,但是您可以手动触发对象/集合的更改事件:

 object.trigger("change"); 

我没有发现它logging在任何地方,但“全部”事件触发所有行动,包括添加,删除和更改。

 var c = new AwesomeCollection(); c.bind("all", function(){ console.log('Something happened'); }); c.add({testModel: "Test"}); 

我希望AwesomeCollection是一个BackboneCollection。

 var AwesomeCollection = new Backbone.Collection(); AwesomeCollection.bind('add', function() { console.log('new object in the collection'); }); AwesomeCollection.add({something}); 

这应该激发你的事件。 如果不是的话,别的地方还有另一个问题。

编辑:更改不能像其他人说的添加事件。

另外,我们不能从你的例子中知道,但是如果你想通过简单地传递一个对象来添加模型,那么Collection必须定义它的模型属性。 否则,您必须将模型实例传递给add()。

我在主干0.5.3面临同样的问题。

查看Backbone.Collection.reset()实现(如果您没有提供任何“添加”可选属性,则在fetch()之后调用)503行至511行:

 // When you have more items than you want to add or remove individually, // you can reset the entire set with a new list of models, without firing // any `added` or `removed` events. Fires `reset` when finished. reset : function(models, options) { models || (models = []); options || (options = {}); this.each(this._removeReference); this._reset(); this.add(models, {silent: true}); if (!options.silent) this.trigger('reset', this, options); return this; }, 

这里有两件事很重要:

  this.add(models, {silent: true}); 

这意味着你不会有任何“添加”事件触发。

第二件事是:

  if (!options.silent) this.trigger('reset', this, options); 

这意味着如果你用以下代码replace你的代码

 var c = new AwesomeCollection(); c.bind("reset", function(){ console.log('Collection has changed.'); } c.add({testModel: "Test"}); // Shouldn't this trigger the above log statement? 

它应该工作(为我工作)