Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js get and set nested object attribute

I have a simple question about Backbone.js' get and set functions.

1) With the code below, how can I 'get' or 'set' obj1.myAttribute1 directly?

Another question:

2) In the Model, aside from the defaults object, where can/should I declare my model's other attributes, such that they can be accessed via Backbone's get and set methods?

var MyModel = Backbone.Model.extend({     defaults: {         obj1 : {             "myAttribute1" : false,             "myAttribute2" : true,         }     } })  var MyView = Backbone.View.extend({     myFunc: function(){         console.log(this.model.get("obj1"));         //returns the obj1 object         //but how do I get obj1.myAttribute1 directly so that it returns false?     } }); 

I know I can do:

this.model.get("obj1").myAttribute1; 

but is that good practice?

like image 854
fortuneRice Avatar asked Jun 14 '11 23:06

fortuneRice


2 Answers

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/

like image 135
Domenic Avatar answered Sep 22 '22 04:09

Domenic


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 
like image 30
evilcelery Avatar answered Sep 20 '22 04:09

evilcelery