2
votes

I am using BackBone relational as very useful extension of Backbone.js.

I have an issue however after saving a backbone relational model with a 1 - M relationship.

The problem I am seeing is that, after model.save(), the add: is fired once again for every related model in the collection. This causes an issue with my view as the models are rendered a second time in the master view.

My master view is set up as follows:

 //master view
 initialize: function(){
     _.bindAll(this, 'render', 'renderRelated');
     this.model.bind('change', this.render);
     this.model.bind('add:related', this.renderRelated);
}

This works great on first load and when adding new related models. The problem is that when save is called on the parent model the add:related is fired again for every nested model even when the models have IDs etc. It seems that the save fully repopulates the related collection.

I'm wondering how have other people gotten around this? I was considering:

  1. attaching the nested view to each related model
  2. bind rm:related to a method that will remove the view from the master view

This seems pretty hacky to me, is very inefficient and will causes a flashing effect for the end user as the sub views are removed and added again.

As part of this I was also trying to bind to the reset:related but that does not seem to fire after the save.

1
Conor, I know this is old but did you ever figure out a solution to this problem? I'm experiencing the same thing and @Tony's answer didn't help in my case.GiantLeprechaun
Looking at the code now, the way we ended up doing it was to bind to sync this.model.bind('sync', this.render) and not use add:related at all and in place of that have a addRelated, renderRelated method which did the work when we needed it. Basically did it manually and couldn't rely on the add:related. So in the parent render() method we loop over each related and render that via our renderRelated() method. Hope that helps.Conor Power

1 Answers

0
votes

I use Backbone.Marionette views, and I had a similar problem. This is how solved it:

initialize: function(){
   this.bindTo(this.model, 'change', this.render);
   this.bindTo(this.model.get('myrelated'), 'relational:add', this.render);
}

I think in plain Backbone this translates to (untested):

initialize: function(){
    _.bindAll(this, 'render', 'renderRelated');
    this.model.bind('change', this.render);
    this.model.get('myrelated').bind('relational:add', this.render);
}

Note that if you're pass {wait: true} when you save, then the relational:add will be fired twice: once when the temporary model is created by backbone before the save, and once when the save succeeds and the actual model is created. This is a bug with Relational that hasn't been resolved yet.