我有一个Collection,其中Collection中的每个项目本身都是一个Collection。我可以渲染集合中的每个项目,实际上可以呈现任何本身都是集合的项目。我遇到的问题是如何呈现这种结构,其中HTML反映了数据结构的层次结构特性。目前,层次结构已经扁平化,最终我得到了一长串<div>
元素。
我为Collection中的每个项目都有一个View,它渲染单个项目并检查是否存在任何嵌套项目需要渲染:
ItemView = Backbone.View.extend({
el: $("div#ItemView"),
initialize: function() {
_.bindAll(this, 'render');
},
render: function() {
// Render a single item from the Collection
$(this.el).append('<div id=' + this.model.id + '></div>');
// Create a View to render the nested Collection
var collectionView = new CollectionView({ collection: this.model.nestedCollection });
collectionView.render();
return this;
}
});
现在这可能是我的问题所在,但CollectionView将为它需要呈现的每个项目创建一个ItemView。这就是如何处理层次结构的递归性质,但是由于ItemView总是具有相同的$(“div#ItemView”)元素,因此会发生展平。
CollectionsView = Backbone.View.extend({
initialize:function() {
_.bindAll(this, 'render');
},
render: function() {
var self = this;
// Iterate over collection, rendering each item
_(this.collection.models).each( function( item ) {
var itemView = new ItemView({model: item});
itemView.render();
}, this);
return this;
}
});
我希望能够将项目附加到不是$("div#ItemView")
的“父”元素。我希望最终得到的HTML结构类似于:
<div>
<div>...</div>
<div>
<div>...</div>
...
</div>
...
</div>
我在这里画了一个角落吗?
答案 0 :(得分:1)
在我的Backbone.Marionette框架中,我有一个名为“CompositeView”的视图类型,它以这种方式工作。
CompositeView的基本思想是它可以在同一视图中呈现模型和集合。
它可以使用模板渲染单个模型。它还可以从该模型中获取集合,并为该集合中的每个模型呈现视图。默认情况下,它使用您定义的相同复合视图类型来渲染集合中的每个模型。您所要做的就是通过initialize
方法告诉视图实例集合的位置,并且您将获得呈现的递归层次结构。
我在JSFiddle中有一个工作演示,在这里:http://jsfiddle.net/derickbailey/AdWjU/
您可以在这里获取Marionette的源代码和文档:https://github.com/derickbailey/backbone.marionette
我知道我并没有直接回答你的问题,但除了你的想法之外,还有很多东西。希望演示和插件对你有所帮助。
答案 1 :(得分:0)
我找到了一个解决方案......它不会感觉'类似于框架',但它很简单,似乎有效。
我有两个观点:
一般流程如下:
ItemView.render()通过将<div>
元素附加到页面中的已知HTML元素来呈现自身。接下来的工作是为它包含的Collection创建一个CollectionView。然后,CollectionView为集合中的每个项创建一个ItemView。
解决方案是:
在ItemView附加了自己并且这样做之后创建了一个新的<div>
,我将CollectionView的el
属性设置为新附加的<div>
。然后,CollectionView使用其更新的el
属性来设置它为集合中的每个Item创建的ItemView的el
属性。然后,当每个ItemView呈现自己时,它正在对其“父”<div>
执行此操作。