新手骨干问题:
背景信息:构建带主干的购物清单
我有一个名称,描述和标签(数组)属性的模型类。 我想基于这个模型或这个模型的集合创建两个视图。
第一个视图将显示如下所有项目:
<ul>
<li><h3>Item 1 Name</h3>
<p>Item 1 Description</p>
<p>Tag1, Tag2 ,Tag3</p>
</li>
.......
</ul>
第二个视图将显示标签列表和标记项目数量,如下所示:
<ul>
<li>Tag1<span>{count of items tagged with tag1}</span></li>
<li>Tag2<span>{count of items tagged with tag2}</span></li>
<li>Tag3<span>{count of items tagged with tag3}</span></li>
</ul>
我构建了模型,集合和视图以支持第一个视图。我想知道使用现有模型(或创建新模型?)的正确方法来构建第二个视图。
提前致谢...
现有项目模型和集合(从Todo.js示例中删除)
window.Item = Backbone.Model.extend({
// Default attributes for a todo item.
defaults: function() {
return {
order: Items.nextOrder()
};
}
});
window.ItemList = Backbone.Collection.extend({
model: Item,
localStorage: new Store("items"),
nextOrder: function() {
if (!this.length) return 1;
return this.last().get('order') + 1;
},
comparator: function(item) {
return item.get('order');
}
});
更新:即使在显示带有项目计数的标记名称时覆盖parse()方法,我也无法在添加新项目后刷新标记名称/项目计数列表。这可能是由于视图是从不同的集合呈现的。我将尝试扩展ItemList集合并覆盖parse()方法。非常感谢任何帮助。
答案 0 :(得分:12)
@machineghost是对的;模型完全与视图分离,因此您可以根据需要将相同模型的视图添加到多个视图中。如果它们具有您想要共享的逻辑或属性,您还可以扩展视图。当我使用Backbone时,我经常发现自己扩展父视图只是为了覆盖render
函数,或提供不同的模板。
ShoppingCartView = Backbone.View.extend({
model: ShoppingCart
...
});
CheckoutView = Backbone.View.extend({
model: ShoppingCart
...
});
CheckoutView = ShoppingCartView.extend({
template: a_different_template // syntax depends on your templating framework
...
});
答案 1 :(得分:3)
我自己对Backbone.js很陌生,所以请耐心等待这个答案,但我想......你只是做出第二个观点。解耦模型和视图的全部意义在于,如果你想做的就是做一些与你的观点不同的事情,你就不需要对模型做任何事情。
所以,我认为你只需要创建YourView2,告诉它使用与YourView1相同的模型,你就应该开展业务。
答案 2 :(得分:3)
来自Backbone.js谷歌集团的Paul Yoder提供了解决方案。 您可以查看here
答案 3 :(得分:0)
经过一番研究后,我发现Collection.Parse方法似乎是在fetch()操作后转换响应的正确位置。看起来我需要一个新的集合模型,集合和视图对象。这就是我在我的集合对象中实现解析函数的方法。在Chrome中成功测试过。随意提出改进建议
<snip>
parse: function(response) {
var items = response; //the raw item model returned from localStorage
var tagNameItemCount = [];
var selectedTags = ["Tag1", "Tag2", "Tag3"];
for(i = 0; i < selectedTags.length; i++){
var currentTagName = selectedTags[i];
var currentItemCount = this.getItemsCountByTagName(currentTagName, items);
tagNameItemCount.push({tagName: currentTagName, tagCount: currentItemCount});
}
return tagNameItemCount;
},
getItemsCountByTagName: function (tagName, items) {
var taggedItems = _.filter(items, function(item){ return _.include(item.tags, tagName); });
return taggedItems.length;
},
</snip>