我正在构建一个小的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?
谢谢!
答案 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
方法,以便在name
或firstName
更改时更新lastName
并忽略当有人试图将name
更改传递给name
时,任何直接尝试更改set
或抱怨“尝试编辑只读属性”的行为。没有任何内容表明validate
无法更改所提供的属性对象,因此您可以在{firstName: 'x'}
返回之前将其更改为{firstName: 'x', name: 'x ' + this.get('lastName')}
并将其更改为validate
。这有点滥用validate
,但没有明确禁止validate
改变属性集,它是你唯一的钩子。我想你可以让模型在自己的firstName
和lastName
上听取更改事件,然后触发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
}
}