简体   繁体   中英

Backbone.js: Collection's “change” event isn't firing

I have a pretty simple collection, but I can't seem to bind to it's change event. In Chrome's console, I'm running:

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?

Since this is one of those things that can be difficult to track down, I doubt anybody knows off the top of their head what's going on (if so, great!). So, I'm asking two questions:

  1. Should the above code work as anticipated?
  2. If so, do you have any suggestions on how to track down where this would fail?

Thanks

The change event is only fired when one of the collections' models are modified. When a model is added to the collection the add event is fired.
See Backbone.js' Collection Documentation :

You can to bind "change" events to be notified when any model in the collection has been modified, listen for "add" and "remove" events[...]

To listen for when an add occurs modify your code to be

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

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

No, that only raises the "add" event. It will raise the change event if you do this:

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

If you want to know when something of significance has been done with a collection, these are the events you probably want to listen to: change add remove reset

With respect to your example, this is what your code might look like:

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

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

object.trigger("change");

I don't find it documented anywhere but the "all" event fires on all actions, including add, remove and change.

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

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

I hope AwesomeCollection is a BackboneCollection.

var AwesomeCollection = new Backbone.Collection();

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

AwesomeCollection.add({something});

This should fire your event. If not, there is another problem somewhere else.

Edit: change can't be fired on add event like others said.

Also, we cannot tell from your example, but a Collection must have its model property defined if you want to add models to it by simply passing an object. Otherwise, you must pass a model instance to add().

I faced the same issue as yours on backbone 0.5.3.

Looking at Backbone.Collection.reset() implementation (which is called after a fetch() if you don't provide any "add" optional property), line 503 to 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;
},

2 things are important here :

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

which means you won't have any "add" event triggered.

Second thing is the :

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

Meaning that if you replace your code with :

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?

It should work (worked for me)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM