7

在下划线中使用主干.js 和配套模板引擎时,我注意到大多数示例model.ToJSON()在渲染时调用,而不是仅仅传递model. 我知道我的模板必须修改它检索数据的方式。

我想知道为什么以及我们从 toJSON() 中得到什么好处?

典型例子

在典型的例子model.toJSON()中是在渲染时调用。请注意,为简洁起见,我将模板作为字符串文字放入。

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

另一种方法

我挖掘了主干 0.9.2 和下划线 1.3.3 代码。在主干中,注意到model.toJSON()执行以下操作:_.clone(this.attributes). 在模板渲染引擎中,我编译的模板将传递的数据命名为obj

看到这些片段后,我意识到没有必要克隆属性。相反,我可以直接传入我的模型(尽管模板中有一些语法更改)。就像是 ...

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

查看这两个示例,我能想到调用 toJSON 的唯一原因是:

  • 保护模型数据免受恶意视图的影响
  • 视图在本地修改数据(我认为这不是一个好主意),
  • 视图需要使用数组/字符串语法访问值( obj[ namepart + someindex]

我的问题归结为:为什么我要打电话toJSON()并接受克隆属性的打击,而不是仅仅在我的模板中使用 get() ?

4

2 回答 2

12

也许以下是有道理的:

  1. 插值而不是评估是一个很大的成本。因此,您的模板版本实际上比调用toJSon()和使用评估要慢得多。

  2. 逻辑属于视图而不是模板。只有在必要时才应该在模板中引入 js 代码(以及插值的需要)。

  3. 有人可能会争辩说你应该通过model.attributes而不是model.toJSON()避免克隆。我猜不这样做的原因是为了避免允许模板更改模型的属性。此外,您通常可能希望model.toJSON()使用其他东西来增加结果,这显然是您不想在model.attributes

于 2012-04-26T18:54:20.897 回答
2

一个可能的原因是因为 Backbone.js 的开发人员允许您使用任何您想要的模板引擎,并且许多模板引擎使用简单的 javascript 对象,而不是Backbone 模型。

于 2012-04-25T19:17:58.490 回答