0

Here I have a Backbone.js Model - Contact and a Collection - Contacts with Contact as the Model. I've two views where in one I use collection to list all the contacts and in the second the model directly to show a single contact. But when I'm using the model directly I'm able to get the 'change' event fired while using with the collection the 'change' event, (even 'all' events of the model) is not fired. Am I missing some extra bind here to make it work with collection?

var Contact = Backbone.Model.extend({ 
    defaults: {
        id: 0,
        urlDisplayPicBig: '',
        urlDisplayPicSmall: ''
    },
    initialize: function () {
        this.bind('change', this.doSomething);
    },
    generateUrls: function () { //earlier doSomething()
        ...
    }
    ...
});

var Contacts = Backbone.Collection.extend({ 
    model: Contact,
    ...
});

Update While using both collection & single model instances I have to run generateUrls() to update urlDisplayPicBig & urlDisplayPicSmall based on the 'id' of the model.

Saneef
  • 8,620
  • 7
  • 29
  • 42
  • 2
    Works for me (http://jsfiddle.net/ambiguous/xUSLE/), what are you doing that's different? – mu is too short May 06 '12 at 05:33
  • I think the major difference would be instead of add() I'm using fetch to get JSON from server. But the does the fetch() behaves different in model and collection? – Saneef May 07 '12 at 03:20
  • [`Collection#fetch`](http://documentcloud.github.com/backbone/#Collection-fetch) will create new model instances, existing models get removed from the collection so there is no change event; [`Model#fetch`](http://documentcloud.github.com/backbone/#Model-fetch) changes the model in-place and does trigger a change event. You're calling `fetch` on a collection? – mu is too short May 07 '12 at 03:30
  • Yes, I'm doing fetch in both cases: on Model and also on Collection. – Saneef May 07 '12 at 03:44

1 Answers1

2

When you do fetch on a collection:

the collection will reset

and that will

replace a collection with a new list of models (or attribute hashes), triggering a single "reset" event at the end. [...] Using reset with no arguments is useful as a way to empty the collection.

So a fetch on a collection will remove all the models that are currently in the collection and replace them with brand new model instances. No "change" events will occur, there will only be a single "reset" event.

When you do a fetch on a model:

A "change" event will be triggered if the server's state differs from the current attributes.

So calling fetch is pretty much the same loading the data from the server manually and calling set to change the model.


Summary: Collection#fetch doesn't trigger any "change" events, just a "reset" event; Model#fetch will trigger a "change" event if something changes.


If you just want to add a couple new attributes when creating new model instances then you can add new attributes to the incoming JSON using Model#parse.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Thanks for the clarification. So I assume there is no way to get collection#fetch's 'reset' event inside the model. :( – Saneef May 07 '12 at 05:08
  • @Saneef: Not really, the models don't survive the reset event. Can you update your question to include some information about what `doSomething` needs to do? There might be a better way. – mu is too short May 07 '12 at 05:22
  • I have updated the question with more details. Hope my intention of the event problem is more clear now. – Saneef May 07 '12 at 05:51
  • @Saneef: You can use `Model#parse` for that: http://documentcloud.github.com/backbone/#Model-parse – mu is too short May 07 '12 at 05:56