我第一次使用Backbone.js,并且喜欢它到目前为止。有一件事我现在无法在模型的动态属性中解决。例如,假设我有一个Person模型,我想得到他们的全名:
var Person = Backbone.Model.extend({
getFullName: function () {
return this.get('firstName') + ' ' + this.get('surname');
}
});
然后我可以做person.getFullName()
。但我想让它与其他吸气剂保持一致,更像是person.get('fullName')
。如果不凌乱地覆盖Person#get,我不会看到如何做到这一点。或者这是我唯一的选择?
这是我迄今为止的最重要的选择:
var Person = Backbone.Model.extend({
get: function (attr) {
switch (attr) {
case 'fullName':
return this.get('firstName') + ' ' + this.get('surname');
break;
case 'somethingElse':
return this.doSomethingClever();
break;
default:
return Backbone.Model.prototype.get.call(this, attr);
}
}
});
我认为这并不可怕,但似乎应该有更好的方法。
答案 0 :(得分:52)
这会更简单吗?
var Person = Backbone.Model.extend({
get: function (attr) {
if (typeof this[attr] == 'function')
{
return this[attr]();
}
return Backbone.Model.prototype.get.call(this, attr);
}
});
这样您也可以使用函数覆盖现有属性。你觉得怎么样?
答案 1 :(得分:2)
我认为属性是模型用来为提出问题的来电者提供答案的原材料。我实际上不喜欢让调用者对内部属性结构了解太多。它是一个实现细节。如果这种结构改变了怎么办?
所以我的答案是:不要这样做。
创建一个方法,并隐藏实现细节。它的代码更清晰,并且可以在实施过程中发挥作用。
答案 2 :(得分:1)
Model.get使用的实际属性存储在attribute属性中。你可以这样做:
// function to cross-browser add a property to an object
function addProperty(object, label, getter, setter) {
if (object.defineProperty){
object.defineProperty(object, label, {getter: getter, setter: setter})
}
else {
object.__defineGetter__(label, getter)
object.__defineSetter__(label, setter)
}
}
// inside the initializer of your model, add a property to the attribute object
var Person = Backbone.Model.extend({
initialize: function(attr, options) {
var t = this;
...
addProperty(this.attributes, 'fullName',
function() {return t.get('firstName') + ' ' + t.get('surname'),
function(val) {...}
)
}
})
这将允许您按照要求执行person.get('fullName')。
编辑:要明确,我同意比尔在下面的回答。不应该真的在使用backbone.js的内部实现。特别是因为这是不完整的......那么escape()而不是get()呢?并且setter更复杂,因为它确认,更改通知等...现在我很抱歉我发布了这个:)