在Backbone.js框架中相互追加视图

时间:2012-03-30 17:08:29

标签: backbone.js

我有一个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>

我在这里画了一个角落吗?

2 个答案:

答案 0 :(得分:1)

在我的Backbone.Marionette框架中,我有一个名为“CompositeView”的视图类型,它以这种方式工作。

CompositeView的基本思想是它可以在同一视图中呈现模型和集合。

它可以使用模板渲染单个模型。它还可以从该模型中获取集合,并为该集合中的每个模型呈现视图。默认情况下,它使用您定义的相同复合视图类型来渲染集合中的每个模型。您所要做的就是通过initialize方法告诉视图实例集合的位置,并且您将获得呈现的递归层次结构。

我在JSFiddle中有一个工作演示,在这里:http://jsfiddle.net/derickbailey/AdWjU/

您可以在这里获取Marionette的源代码和文档:https://github.com/derickbailey/backbone.marionette

我知道我并没有直接回答你的问题,但除了你的想法之外,还有很多东西。希望演示和插件对你有所帮助。

答案 1 :(得分:0)

我找到了一个解决方案......它不会感觉'类似于框架',但它很简单,似乎有效。

我有两个观点:

  1. ItemView
  2. 的CollectionView
  3. 一般流程如下:

    ItemView.render()通过将<div>元素附加到页面中的已知HTML元素来呈现自身。接下来的工作是为它包含的Collection创建一个CollectionView。然后,CollectionView为集合中的每个项创建一个ItemView。

    解决方案是:

    在ItemView附加了自己并且这样做之后创建了一个新的<div>,我将CollectionView的el属性设置为新附加的<div>。然后,CollectionView使用其更新的el属性来设置它为集合中的每个Item创建的ItemView的el属性。然后,当每个ItemView呈现自己时,它正在对其“父”<div>执行此操作。