0

I'm stumped on this. I have a simple backbone-relational model:

window.Site = Backbone.RelationalModel.extend({
    idAttribute: "_id",
    // These are the relations to the user model.
    relations: [{
        type: Backbone.HasMany,
        key: 'users',
        relatedModel: 'window.User'
      }],

});

And my user model (which is related to the site model) looks like this:

  //Site User model
  // -------------

  window.User = Backbone.RelationalModel.extend({
    });

The user model is intentionally kept dumb, as I'm still prototyping.

The JSON I receive from the server to hydrate the Site and users looks something like this:

{
_id: foo,
users: [
username: bar,
password: fizz
]}

What I'm stumped on is the listeners. The events that are on the SiteView (which renders my SiteCollection) look like this:

initialize: function() {

  //basic bindings
  this.model.bind('change', this.setSave, this);
  this.model.bind('destroy', this.remove, this);

  // bindings to sub-models
  this.model.bind('add:users', this.setDetailsView, this);
  this.model.bind('remove:users', this.setSave, this);
  this.model.bind('change:users', this.setSave, this);

The add:users and remove:users events fire fine, but the change:users event does not. In the DetailsView, which renders my Users models, I also have some simple event bindings:

initialize: function() {
  this.model.bind('change', this.render, this);
  this.model.bind('destroy', this.remove, this);

But, for some reason, the change:users event in the SiteView does not fire, while the change event in the DetailsView does.

Could this be because:

  • The change event on the Users models is bound twice in two different views?
  • The Users model is not bidirectional?
CamelBlues
  • 3,444
  • 5
  • 29
  • 37

2 Answers2

2

To me it looks like the update: event does not work exactly as you would anticipate. From my understanding, it only fires, if the key, i.e. the related model changes, but not if you change its attributes. This means, only if you switch from one user to the other, it would fire, not if you change the attribute of an existing user. This is my understanding of line 711 of the source code. What might work is something along those lines:

this.model.get('users').each(function(user){
    user.bind(change,this.render,this);
},this);
schacki
  • 9,401
  • 5
  • 29
  • 32
  • Thanks! This does work, but I think that the `update` event can be triggered in the way I anticipate by setting up a `reverseRelation` on my model. Still trying to figure out how to do that... but this is a good fix for now! – CamelBlues Aug 15 '12 at 21:42
  • great that it works, let us know, if the reverse approach works – schacki Aug 15 '12 at 22:04
  • 1
    Works like a charm! The `reverseRelation` had no effect – CamelBlues Aug 24 '12 at 02:18
  • 1
    In the case of adding and removing items from the collection, wouldn't you have to unsubscribe and resubscribe change tracking from each item? – Trevor Elliott Jun 28 '13 at 14:33
0

Better solution :

this.model.bind('relational:change:users', this.setSave, this);
Gmajoulet
  • 700
  • 4
  • 8