在Backbone中使用覆盖的getter渲染视图

时间:2011-11-23 22:13:22

标签: json templates backbone.js render getter

我正在构建一个小的Backbone.js应用程序,并在其中一个模型中添加了一些自定义getter(名称getter返回一个连接的名字和姓氏):

PersonModel = Backbone.Model.extend({
  get: function (attr) {
    if (typeof this[attr] == 'function') {
      return this[attr]();
    }
    return Backbone.Model.prototype.get.call(this, attr);
  },

  name: function() {
    return firstName + " " + lastName;
  }
})

我现在可以使用person.get("name")来检索名称,很好。但是,当我在模型上调用toJSON时,这些值不包括在内(我认为这是有意义的)。问题是我使用它来渲染我的观点:

this.template({people: this.collection.toJSON()});

在Backbone.js中执行此操作的最佳方法是什么?使用覆盖的getter手动创建JSON?

谢谢!

2 个答案:

答案 0 :(得分:5)

您可以在PersonModel上提供自己的toJSON方法:

toJSON: function() {
    var attr = Backbone.Model.prototype.toJSON.call(this);
    attr.name = this.name();
    return attr;
}

collection toJSON只需在每个型号上调用toJSON

// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
  return this.map(function(model){ return model.toJSON(); });
},

因此,将自己的toJSON添加到模型中应该可以正常工作。

您还可以将name添加为真实属性,然后调整模型的validate方法,以便在namefirstName更改时更新lastName并忽略当有人试图将name更改传递给name时,任何直接尝试更改set或抱怨“尝试编辑只读属性”的行为。没有任何内容表明validate无法更改所提供的属性对象,因此您可以在{firstName: 'x'}返回之前将其更改为{firstName: 'x', name: 'x ' + this.get('lastName')}并将其更改为validate。这有点滥用validate,但没有明确禁止validate改变属性集,它是你唯一的钩子。我想你可以让模型在自己的firstNamelastName上听取更改事件,然后触发set({name: ...}),但如果其他人只看第一个,你可能会遇到事件排序问题和姓氏。

答案 1 :(得分:0)

我选择扩展主干模型并让我的所有应用模型从包含方法的Base模型扩展,以便启用设置虚拟属性并将其合并到模型toJSON方法中。

  toJSON: function() {
    return _.extend(toJSON.__super__.constructor.apply(this, arguments), this.getVirtualAttributes());
  },
  getVirtualAttributes: function() {
    var attrs, key;
    attrs = {};
    for (key in this.virtualAttributes) {
      attrs[key] = this.virtualAttributes[key].call(this);
    }
    return attrs;
  }

这允许您在模型上定义virtualAttributes对象,该对象可用于检索虚拟/动态属性。

virtualAttributes: {
  email_length: function() {
    return this.get("email").length
  }
}