我有一个骨干模型(我们称之为Foo
),其中包括n个子模型的集合(我们称它们为Bar
),在一个特定的视图中,我只想显示这些子模型的m,以及一条消息,如"(n-m)剩余"。
现在,我得到的是这样的东西:
var FooView = Backbone.View.extend({
...
render: function() {
this._barViews = [];
var bars = this.model.get("bars");
var that = this;
_.each(bars.first(maxToShow), function(bar) {
that._barViews.push(new BarView({model:bar}));
}
var remaining = bars.length - maxToShow;
this.model.set("remaining", remaining > 0 ? remaining : undefined;
var json = this.model.toJSON();
$(this.el).html(this.template(json));
_(this._holdViews).each(function(hv) {
holdList.append($(hv.render().el));
});
}
});
这有效,但感觉很笨拙,因为我将"remainingMessage"注入到模型中,即使这是特定于此特定视图的。(另一个视图可能会显示所有bars
,或者不显示任何,并且可能有也可能没有剩余消息。我对嵌套视图也不是完全兴奋,因为它们意味着创建一个额外的模板文件并且必须记住包含它(FWIW,我正在使用 Handlebars.js 作为模板,具有服务器端编译)。
有没有更好的方法来 (1) 将bars
集合过滤为maxShown
项,以及 (2) 生成/包含视图中剩余的数量?
您需要一个"视图模型" - 一个专门用于处理将使用它的特定视图的模型。幸运的是,这在 JavaScript 中非常简单。
使用 Object.create
您可以获取一个新的对象实例,该实例继承自作为参数传入的原始对象。这使我们能够使用新代码"装饰"原始模型,而无需实际更改原始模型。
在您的情况下,我们希望使用剩余信息装饰"foo"模型。但是,我们只需要toJSON
结果中的信息,因此我们只会将其添加到该方法中。
function buildFooViewModel(model){
var foovm = Object.create(model);
foovm.toJSON = function(){
// call the original model's toJSON
var args = Array.prototype.slice.apply(arguments);
var json = model.toJSON.apply(this, args);
// add the needed "remaining" data using your calculations, here
json.remaining = bars.length - maxToShow;
// send the json data back
return json;
}
}
var FooView = Backbone.View.extend({
initialize: function(){
// use the view model instead of the original
this.model = buildFooViewModel(this.model);
},
render: function(){
// your normal render stuff here... calling this.model.toJSON
// will return your JSON data with the `remaining` field in it already
}
});
我经常对需要这样计算的观点这样做。您可以看到它发生在 http://ravenhq.com 各地,例如,在数据库管理屏幕中,已用/剩余百分比以及其他类似的值。