Backbone.js get and set nested object attribute
While this.model.get("obj1").myAttribute1
is fine, it's a bit problematic because then you might be tempted to do the same type of thing for set, i.e.
this.model.get("obj1").myAttribute1 = true;
But if you do this, you won't get the benefits of Backbone models for myAttribute1
, like change events or validation.
A better solution would be to never nest POJSOs ("plain old JavaScript objects") in your models, and instead nest custom model classes. So it would look something like this:
var Obj = Backbone.Model.extend({ defaults: { myAttribute1: false, myAttribute2: true }});var MyModel = Backbone.Model.extend({ initialize: function () { this.set("obj1", new Obj()); }});
Then the accessing code would be
var x = this.model.get("obj1").get("myAttribute1");
but more importantly the setting code would be
this.model.get("obj1").set({ myAttribute1: true });
which will fire appropriate change events and the like. Working example here: http://jsfiddle.net/g3U7j/
I created backbone-deep-model for this - just extend Backbone.DeepModel instead of Backbone.Model and you can then use paths to get/set nested model attributes. It maintains change events too.
model.bind('change:user.name.first', function(){...});model.set({'user.name.first': 'Eric'});model.get('user.name.first'); //Eric
Domenic's solution will work however each new MyModel will point to the same instance of Obj. To avoid this, MyModel should look like:
var MyModel = Backbone.Model.extend({ initialize: function() { myDefaults = { obj1: new Obj() } this.set(myDefaults); }});
See c3rin's answer @ https://stackoverflow.com/a/6364480/1072653 for a full explanation.