When using backbone.js and the companion templating engine in underscore, I’ve noticed that most examples call model.ToJSON() when rendering instead of just passing model. I understand that my template would have to modify how it retrieves data.
I’m wondering why & what benefit do we get from toJSON()?
Typical Example
In the typical example model.toJSON() is called when rendering. Note, for the sake of brevity, i put the template in as a string literal.
ToDoItemView = Backbone.View.extend({
/* other viewey stuff */
template : _.template( '<li><%=ToDoNote%></li>'),
render : function () {
var out= this.template(this.model.toJSON()); //<--JSON
$(this.el).html( out) }
return this;
}
}); //end view
An Alternate Method
I dug through the backbone 0.9.2 & underscore 1.3.3 code. In backbone, noticed that model.toJSON() does the following: _.clone(this.attributes). Inside the template rendering engine, my compiled template names the passed-data obj.
After seeing those snippets, I realized that cloning the attributes isn’t necessary. Instead, I can directly pass in my model (albeit, with some syntax changes in the template). Something like …
ToDoItemView = Backbone.View.extend({
/* other viewey stuff */
template : _.template( '<li><%=obj.get('ToDoNote')%></li>'), //<--notice GET()
render : function () {
var out= this.template(this.model); //<-- look ma no json
$(this.el).html( result ) }
return this;
}
}); //end view
Looking at the two examples, the only reasons I can come up with to call toJSON are :
- protect model data from a nefarious view
- the view locally modifies data (not a good idea in my opinion),
- view needs to access values using array/string syntax(
obj[ namepart + someindex])
My question boils down to : why would I call toJSON() and take the hit for cloning the properties, rather than just use get() in my templates?
Maybe the following makes sense:
Interpolating instead of evaluating is a big cost to take. So your version of the template is actually a lot slower than calling
toJSon()and using evalution.Logic belongs to views not templates. Introducing js code (and the need for interpolation) in templates should only be done if necessary.
One could argue that you should be passing
model.attributesinstead ofmodel.toJSON()avoiding the clone. I guess the reason for not doing so is to avoid allowing the template to change the model’s attributes. In addition, you might typically want to augment the result ofmodel.toJSON()with other things, which obviously you don’t want to do on themodel.attributes