Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone/Underscore Template -- when rendering why call toJSON?

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?

like image 584
EBarr Avatar asked Apr 25 '12 18:04

EBarr


2 Answers

Maybe the following makes sense:

  1. 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.

  2. Logic belongs to views not templates. Introducing js code (and the need for interpolation) in templates should only be done if necessary.

  3. One could argue that you should be passing model.attributes instead of model.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 of model.toJSON() with other things, which obviously you don't want to do on the model.attributes

like image 118
ggozad Avatar answered Sep 30 '22 23:09

ggozad


A likely reason is because the developers of Backbone.js have allowed you to use any templating engine you desire, and many templating engines work off of simple javascript objects, not Backbone Models.

like image 26
JayC Avatar answered Sep 30 '22 23:09

JayC