【问题标题】:Marionette CompositeView as itemView of its own itemView (circular recursion?)Marionette CompositeView 作为自己 itemView 的 itemView(循环递归?)
【发布时间】:2014-03-02 16:25:29
【问题描述】:

这里有一个有趣的。我有两个 CompositeView,CategoriesViewCategoryView,我有一个嵌套的类别集合,其中每个类别可能有 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        | |
...

我遇到的问题是我无法将CategoryViewitemView 属性定义为CategoriesView,因为该对象稍后在脚本文件中定义。这会导致CompositeView 将自己用作itemView

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');
    }
});

(旁注:我使用 Bootstrap 的 panelcollapse 将每个类别组呈现为自己的面板。)

现在,它将顶级类别呈现为面板,并将下面的所有内容呈现为列表。

有没有更好的方法来处理这种嵌套的视图关系?我敢肯定,如果需要,我可以一起破解一些东西,但我宁愿以“正确”的方式来做。 :) 还是我应该忘记它并通过在 CategoryView 上省略 itemView 来走嵌套列表路线,以便它使用自己?

【问题讨论】:

  • 我刚刚找到this post,它回答了未定义的 itemView 问题并让我走上了正轨。当我完全正常工作时,我会更新一个真实的答案。

标签: backbone.js twitter-bootstrap-3 marionette


【解决方案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

【讨论】:

  • 谢谢!这肯定会解决我遇到的一个问题(将 itemView 分配给文件中稍后定义的类),但这并不是我需要发生的。请参阅下面的答案。
【解决方案2】:

我最终做的是重写 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 开箱即用的传统树/叶模式的更复杂的布局。

【讨论】:

    猜你喜欢
    • 2017-11-08
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多