Backbone.js:Collection的“更改”事件未触发

时间:2011-11-17 22:06:58

标签: javascript 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. 如果是这样,您对如何追踪失败的地方有什么建议吗?
  3. 由于

8 个答案:

答案 0 :(得分:68)

change事件仅在修改其中一个集合的模型时触发。将模型添加到集合时,会触发add事件 请参阅Backbone.js'Collection Documentation

  

你可以绑定“更改”事件,以便在任何模型中通知   集合已被修改,听取“添加”和“删除”   事件[...]

要在add发生时收听,请将您的代码修改为

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

c.add({testModel: "Test"}); 

答案 1 :(得分:11)

不,这只会引发“添加”事件。如果你这样做,它会引发变化事件:

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"});

答案 2 :(得分:10)

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

关于您的示例,这就是您的代码的样子:

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

答案 3 :(得分:5)

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

object.trigger("change");

答案 4 :(得分:1)

我没有在任何地方找到它,但“all”事件会触发所有操作,包括添加,删除和更改。

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

c.add({testModel: "Test"}); 

答案 5 :(得分:0)

我希望AwesomeCollection是一个BackboneCollection。

var AwesomeCollection = new Backbone.Collection();

AwesomeCollection.bind('add', function() {
    console.log('new object in the collection');
});

AwesomeCollection.add({something});

这会触发您的活动。如果没有,其他地方还有另一个问题。

编辑:像其他人说的那样,无法在添加事件上触发更改。

答案 6 :(得分:0)

此外,我们无法从您的示例中看出,但如果您想通过简单地传递对象来向其添加模型,则Collection必须定义其模型属性。否则,您必须将模型实例传递给add()。

答案 7 :(得分:0)

我在主干0.5.3上遇到了与你相同的问题。

查看Backbone.Collection.reset()实现(如果你没有提供任何“add”可选属性,则在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);

这意味着如果用以下代码替换代码:

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?

应该有效(为我工作)