使用CollectionView创建Sibling ItemViews?

时间:2012-02-27 23:35:53

标签: javascript backbone.js

我有一个使用CollectionView输出以下内容的backbone.marionette应用程序:

  • div #main .widget
    • div.head
    • div.body

以下是2个兄弟的ItemViews:

var LogLocationBodyView = App.ItemView.extend({
    tagName: "div",
    attributes: {class: "body"},
    template: "#log-location-body-template"
});

var LogLocationHeadView = App.ItemView.extend({
    tagName: "div",
    attributes: {class: "head"},
    template: "#log-location-head-template" 
});

这是CollectionView:

var LogLocationsView = App.CollectionView.extend({
    template: "#log-locations-template",
    attributes: {id: "main", class: "widget"},
    itemView: LogLocationHeadView
});

我显然可以使用LogLocationHeadView进行渲染,但我正在寻找inserAfter()LogLocationBodyView的最佳方法,以便2个ItemViews是兄弟姐妹。

最好的办法是什么?我尝试了很多不同的方法。首先我尝试使用我的ItemView的onRender(),但很快意识到我只能附加到视图中的标记。我真的需要insertAfter()并且parent不可用,因为在onRender中我们仍然是pre-DOM插入。

var LogLocationHeadView = App.ItemView.extend({
    tagName: "div",
    attributes: {class: "head"},
    template: "#log-location-head-template",
    onRender: function() {

        // create a new piece of html from a different template
        var view = new LogLocationBodyView({
            model: this.model
        });

        view.render();

        $(this.el).append(view.el);

        var c = $(this.el).children();
            console.log(c); // true

        var p = $(this.el).parents();
            console.log(p); //undefined

    }

我也理解我可以覆盖CollectionViews中的appendHTML()和renderItem()方法,但我仍然需要append()。所以我需要能够传递一个renderType。

我真正想做的是将一个ItemViews数组和一个renderType传递给renderItem。然后,renderItems可以在appendHTML()内进行分叉。

var LogLocationsView = App.CollectionView.extend({
    template: "#log-locations-template",
    attributes: {id: "main", class: "widget"},
    itemViews: [{view: LogLocationHeadView, renderType: append}, {view: LogLocationBodyView, renderType: insertAfter}]
});

在我尝试这样做之前,我想知道我是否完全不在这里。有一个更好的方法吗?

2 个答案:

答案 0 :(得分:0)

最好也是最干净的方法是让标题和正文视图的父视图将这些视图附加到render方法中,而不是依赖insertAfter。如果您想要从尚未插入的视图中处理它但将在当前浏览器事件循环的末尾处理,您可以使用下划线defer方法或者方法将视图推迟到下一个循环中。 setTimeout(fn,1)方法。

和btw。如果tagName是div,则不需要指定tagName,因为div是tagName的默认值。

答案 1 :(得分:0)