【问题标题】:Backbone/Underscore Template -- when rendering why call toJSON?Backbone/Underscore 模板——渲染时为什么调用 toJSON?
【发布时间】:2012-04-25 18:54:53
【问题描述】:

当在下划线中使用backbone.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

在看到那些 sn-ps 之后,我意识到克隆属性是没有必要的。相反,我可以直接传入我的模型(尽管模板中有一些语法更改)。有点像...

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()?

【问题讨论】:

  • “克隆成功”?你认为拨打get 是免费的吗?
  • @muistooshort -- 免费?不。 Get()return this.attributes[attr];。那么数组查找比数组克隆更快吗?是的——从资源和时间两方面来说,但这不符合我的观点。调用toJSON() 显然是骨干社区集体思维的一部分。我很好奇为什么。
  • “重复的函数调用和对象访问”与“一个克隆和重复的对象访问”相比,我没有看到任何基准测试结果,所以您的 Yes 只是意见(就像所有答案都将是,因此“非建设性”投票)。并非每个视图都将是模型或集合的直接映射,toJSON 更灵活并减少了模板中的噪音。
  • 抱歉,您似乎对此很生气。您关于“不一定是直接映射”的理由是一个很好的建设性答案。
  • 我没有生气,cmets 需要简短,我认为这种讨论不属于这里,无关个人。

标签: backbone.js underscore.js


【解决方案1】:

也许以下是有道理的:

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

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

  3. 有人可能会争辩说,您应该传递 model.attributes 而不是 model.toJSON() 以避免克隆。我猜不这样做的原因是为了避免允许模板更改模型的属性。此外,您通常可能希望使用其他内容来扩充 model.toJSON() 的结果,这显然是您不想在 model.attributes 上执行的操作

【讨论】:

  • 说得好。很有道理。
  • 应该注意的是,建议不要使用model.toJSON() 用于视图...它用于序列化模型以进行同步,而不是渲染。你应该按照你的建议通过model.attributesgithub.com/jashkenas/backbone/issues/2134
  • 即使使用 toJSON()_.clone() 也不能完全阻止模板更改模型的属性,因为 clone 方法会创建“对象的浅拷贝克隆。任何嵌套的对象或数组都将被通过引用复制,而不是复制。” (underscorejs.org/#clone) 所以,我建议使用model.attributes,但请注意,在任何情况下都不要从模板中更改模型。
【解决方案2】:

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

【讨论】:

  • 好点。虽然,我特别在谈论为什么/为什么不选择这个策略作为下划线模板
猜你喜欢
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 2015-04-23
  • 1970-01-01
相关资源
最近更新 更多