Backbone.js - 如何在模板中使用自定义模型属性?

Posted

技术标签:

【中文标题】Backbone.js - 如何在模板中使用自定义模型属性?【英文标题】:Backbone.js - How to use a custom model property in a template? 【发布时间】:2012-06-02 11:42:54 【问题描述】:

这可能是一个非常简单的问题,但我很难找到答案。

使用主干,我有这条线:

Person = Backbone.Model.extend();

然后我在从 URL 填充的集合中使用它。为了这个例子,假设我有一个名字和姓氏,我想做一些类似的事情:

Person = Backbone.Model.extend(
    FullName: this.get("firstName") + " " + this.get("lastName")
);

我可以使用例如 People.first().FullName() 来调用内部主干。但是,如果我将 People.first() 传递给我的视图并在模板中呈现它,它似乎不知道 FullName 是什么。

如何将自定义属性添加到 Backbone 中的模型并在模板中使用它?

干杯!

【问题讨论】:

你应该在初始化时这样做。例如:Person = Backbone.Model.extend( initialize:function() this.set("FullName":this.get("FirstName") + " " + this.get("LastName")); //using set will trigger change event :) ); 【参考方案1】:

你的FullName 定义没有任何意义,所以我会假设你真的是这个意思:

Person = Backbone.Model.extend(
    FullName: function() 
        return this.get("firstName") + " " + this.get("lastName");
    
);

通常你会在你的模型上调用toJSON 来序列化它们以供模板使用:

var html = template( person: person.toJSON() )

default toJSON 仅返回模型内部属性的(浅)副本。这些属性可能同时具有firstNamelastName 属性,但FullName 是模型上的一个函数,因此它不会出现在属性中。

您可以提供自己的toJSON

toJSON: function() 
    var j = _(this.attributes).clone();
    j.FullName = this.FullName();
    return j;

然后你的模板中有一个FullName。不过toJSON也是用来序列化模型向服务器发送数据的;您的服务器最终会看到FullName,它可能会对此感到不安。您可以专门为模板添加另一个序列化程序:

// `serialize` is another common name for this
for_template: function() 
    var j = this.toJSON();
    j.FullName = this.FullName();
    return j;

然后使用该函数为您的模板提供数据:

var html = template( person: person.for_template() );

【讨论】:

完全同意,我首选的方法是for_template 一种,我不喜欢和toJSON 这样的非常核心的方法纠缠在一起。相关回答***.com/questions/9642439/… 使用for_template的好主意 @fguillen:是的,这种事情已经出现过几次了。有一个parse 方法,但没有unparsetoJSON 正在为视图序列化事物和为持久性序列化事物,但这些是不同的任务。以一种或另一种方式修补 Backbone 将非常简单,unparse 会更向后兼容,但由于the specialness of toJSONfor_template 对我来说更有意义。【参考方案2】:

我也为此苦苦挣扎了一段时间,但我找到了解决办法。

它涵盖了相当多的深度,包括解决 toJSON 被用于发送服务器数据的问题,Backbone Computed Properties

【讨论】:

【参考方案3】:
var Person = Backbone.Model.extend(
    parse: function (model) 
        model.FullName = model.FirstName + ' ' + model.LastName;
        return model;
    
);

【讨论】:

这种方法的问题是model.toJSON() 现在将包含一个FullName,这意味着当你model.save() 时服务器会看到一个意外的FullName。明智的服务器代码会抱怨该 API 违规。您还必须担心在创建模型时未调用 parse 的情况。 通过覆盖model.save同样去除全名【参考方案4】:

还有一个更简单的方法。将您的方法包含在您的初始化方法中。当您实例化您的模型时,您的所有方法也会被实例化。

var model = Backbone.Model.extend(
 initialize : function()
      this.myCustomMethod = function() return 'Something'; ;
 ,
 idAttribute : 'id',
 urlRoot : ''
 );

【讨论】:

这与问题有什么关系?【参考方案5】:

完全不同的解决方法:

Backbone.Model.extend(
  defaults: function() 
    this.set('fullName', this.fullName.bind(this))
  ,

  fullName: function() 
    return this.get('firstName') + this.get('lastName');
  
);

这样可以直接在模型上调用“fullName”函数

model.fullName()

或通过get函数,允许从模板调用:

model.get('fullName')()

【讨论】:

以上是关于Backbone.js - 如何在模板中使用自定义模型属性?的主要内容,如果未能解决你的问题,请参考以下文章

Backbone.js 如何在表格列表中选择组合框选项?

使用backbone.js 从视图访问模型数据

渲染 Backbone.js 集合

Backbone.js:模板无法识别模型

Backbone.js:为 Backbone.sync 实现定义超时

backbone-1.3.3源码解析-----------Event