0

Here is some code:

var TopPanel = Backbone.View.extend( {
    initialize: function() {
        this.listenTo(this.model, "change", this.render);
    },
    render: {
       ...
    }
});


var MyData = Backbone.Model.extend({
    initialize: function() {
    },
    defaults: {
        team: {
        level:0,
            name: "bla"
        }
    }
});

var myData = new MyData();
var topPanel = new TopPanel({model: myData});
topPanel.render();
var anotherView = new AnotherView( {model: myData} );

In Another view I am changing the model on button click like this:

var team = this.model.get("team");
team.level = 1;
this.model.set("team", team);

When I press the button in Another View, it changes model as written above, but render function of the topPanel View doesn't invoked. However if I change the code above like: var team = this.model.get("team"); team = 1; this.model.set("team", team);

The render function is invoked.

Does this mean that backbone.js doesn't support listening for changes in complex objects in Model ? If it does, what is a correct way to do it?

maximus
  • 4,201
  • 15
  • 64
  • 117
  • 2
    This is kind of a dupplicate question, see [this question](http://stackoverflow.com/questions/6351271/backbone-js-get-and-set-nested-object-attribute) – balazs Jun 03 '13 at 07:40

1 Answers1

3
var team = this.model.get("team");
team.level = 1;
this.model.set("team", team);

Here you're actually not changing the team attribute as you think you are. You're altering it only. Your model stores a reference to your JSON object. When you alter this JSON, the reference won't change, therefore there is no change event triggered. This also implies that your last line this.model.set("team", team); is in fact totally useless, because you're trying to set the same object (therefore the same reference) again. Backbone will silently ignore that call.

Now, about what you could do to actually trigger the change:

Solution 1:
Trigger it manually:

this.model.get('team').level = 1;
this.model.trigger('change');

Solution 2:
Create a new object:

var team = _.clone(this.model.get('team'));
team.level = 1;
this.model.set('team', team);

In both those solutions, your model will be changed and the change event will be triggered.

Loamhoof
  • 8,293
  • 27
  • 30