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