这是一个有趣的。我有两个CompositeViews,CategoriesView
和CategoryView
,我有一个嵌套的类别集合,其中每个类别可能有0个或更多子节点。我想渲染该集合,以便任何有孩子的类别都使用CategoriesView
作为itemView
和任何不使用CategoryView
的类别。理想情况下,我希望CategoryView
使用CategoriesView
作为itemView
,反之亦然。所以:
+---------------------------------+
| CategoriesView: Title | <- 4 children
|---------------------------------|
| CategoryView: item 1 | <- 0 children
| CategoryView: item 2 | <- 0 children
| CategoryView: item 3 | <- 0 children
| +-----------------------------+ |
| | CategoriesView: title | | <- 10 children
| |-----------------------------| |
| | CategoryView: item 5 | |
...
我遇到的问题是我无法将CategoryView
的{{1}}属性定义为itemView
,因为该对象稍后在脚本文件中定义。这会导致CategoriesView
将自己用作CompositeView
。
itemView
(旁注:我正在使用Bootstrap的var CategoryView = Marionette.CompositeView.extend({
template: catTpl,
tagName: 'li',
itemView: CategoriesView,
itemViewContainer: '.panel-group',
initialize: function() {
if (this.model.get('children').length) {
this.collection = this.model.get('children');
}
},
onRender: function() {
if (!this.collection) {
this.$(".panel-group").remove();
}
}
});
var CategoriesView = Marionette.CompositeView.extend({
template: groupTpl,
className: "panel panel-default",
itemView: CategoryView,
itemViewContainer: '.panel-body ul',
initialize: function() {
this.collection = this.model.get('children');
}
});
和panel
将每个类别组渲染为自己的面板。)
现在,它将顶级类别呈现为面板,将下面的所有内容呈现为列表。
有没有更好的方法来处理这种嵌套视图关系?我确信如果需要我可以一起破解,但我宁愿以“正确”的方式做到这一点。 :)或者我应该忘记它并通过在collapse
上省略itemView
来使用嵌套列表路线,以便它自己使用?
答案 0 :(得分:1)
这应该有效:
var CategoryView = Marionette.CompositeView.extend({
// don't define the itemView here...
});
var CategoriesView = Marionette.CompositeView.extend({
// edited for brevity
itemView: CategoryView,
// edited for brevity
});
CategoryView.itemView = CategoriesView
答案 1 :(得分:0)
我最终做的是重写getItemView
函数以返回相应的ItemView
类:
// Renders a simple list item
var CategoryView = Marionette.CompositeView.extend({
template: catTpl,
tagName: "li"
});
// Renders a Panel with heading and body and container for list items
var CategoriesView = Marionette.CompositeView.extend({
template: groupTpl,
className: "panel panel-default",
itemViewContainer: '.panel-body ul',
// Reuse this as the itemView if we need to render a sub-list
getItemView: function(item) {
if (item.get('children').length == 0) {
return CategoryView;
} else {
return this.constructor;
}
},
initialize: function() {
this.collection = this.model.get('children');
}
});
// Renders the outermost container
return Marionette.CompositeView.extend({
template: mainTpl,
className: "carousel slide",
attributes: {
"data-interval": false,
"data-wrap": false
},
itemView: CategoriesView,
itemViewContainer: '#categories'
});
这非常有效,并且允许我有一个更复杂的布局,它不太适合CompositeViews开箱即用的传统树/叶模式。