在基本元素之后插入渲染视图

时间:2015-11-22 13:18:42

标签: javascript backbone.js marionette

所以我有一个复合视图。 CompositeView是一个" ul"首先是基地的元素" li"元素和另一个" li"的集合元素。我的目标是在base" li"之后插入每个渲染的子元素集合。元件。

我的观点代码

var
_NavItem = Marionette.ItemView.extend({

    tagName: 'li',
    template: function (serialized_model) {

        return _.template('<a href="/"><span class="<%= name %>"><%= name %></span></a>')(serialized_model);
    }   
});

var
_NavComposite = Marionette.CompositeView.extend({

    tagName: 'li',
    className: 'header',
    childView: _NavItem,
    initialize: function () {

        this.collection = new Backbone.Collection(this.model.attributes.items);
    },
    template: function (serialized_model) {

        return _.template('<%= name %>')(serialized_model);
    },
    attachHtml: function(collectionView, childView){

        collectionView.$el.append(childView.el);
    }
});

var
_NavigationView = Marionette.CollectionView.extend({

    tagName: 'ul',
    childView: _NavComposite
});

实际上这段代码将呈现结构

ul
    li (base0) /li
    li /li (li of collection)
    li /li (li of collection)
    ...
    li (base1) /li
    li /li (li of collection)
    li /li (li of collection)
    ...
    li (base2) /li
    li /li (li of collection)
    li /li (li of collection)
    ...
/ul

但是当我开始时,没有任何事情发生。 如果我将代码更改为

attachHtml: function(compositeView, childView){

    compositeView.$el.append(childView.el);
}

它工作正常,但这会渲染另一个我想要的结构

ul
    li (base0)
        li /li (li of collection)
        li /li (li of collection)
        ...
        li /li (li of collection)
    /li
    li (base1)
        li /li (li of collection)
        li /li (li of collection)
        ...
        li /li (li of collection)
    /li
    ...
/ul

数据结构

[0: { id: 1, name: 'Base li name 1', items: [ 
    0: {id: 2, name: 'Li child 1'},
    1: {id: 3, name: 'Li child 2'}
]}, 
1: { id: 4, name: 'Base li name 2', items: [ 
    0: {id: 5, name: 'Li child 3'},
    1: {id: 6, name: 'Li child 4'}
]}
...
] 

1 个答案:

答案 0 :(得分:2)

更新问题的更新:

由于Backbone.View生成的视图包装器,没有办法获得你想要的结构。你最多可以有多个li,每个li都有li(base)和sibling li(collection)项,但是它们会存在于二级列表中。像这样,

<ul>
   <li>
      <ul>
         <li>
            composite0.model.name
         </li>
         <li>
            childView0.model.name
         </li>
           .
           .
           .
         <li>
            childViewN.model.name
         </li>
     </ul>    
  </li>
    .
    .
    .
  <li>
      <ul>
         <li>
            compositeN.model.name
         </li>
         <li>
            childView0.model.name
         </li>
           .
           .
           .
         <li>
            childViewN.model.name
         </li>
      </ul>
   </li>
</ul>

我认为您真正需要的只是一个CompositeView,您可以利用CompositeView模板来获得您正在寻找的效果:

var _NavItem = Marionette.ItemView.extend({
    tagName: 'li',
    template: function (serialized_model) {

        return _.template('<a href="/"><span class="<%= name %>"><%= name %></span></a>')(serialized_model);
    }   
});

var _NavBaseListView = Marionette.CompositeView.extend({

        tagName: 'ul',
        className: 'header',
        childView: _NavItem,
        template: function (serialized_model) {
            return _.template('<li><%= name %></li>')(serialized_model);
        },
        attachHtml: function(collectionView, childView){        
            collectionView.$el.append(childView.el);
        }
});

工作原理

CompositeView上的模板将返回

<li>
   composite.model.name
</li>

并且当调用CompositeView中的attachHtml时,childView(另一个<li>)将简单地附加在CompositeView模板中描述的基础<li>下方。 (顺便说一句,您根本不必覆盖attachHtml,因为collectionView.$el.append是默认行为[好吧,因为它会缓冲子项然后附加组,但结果相同] )。

最后你会得到

<ul>
   <li>
      composite.model.name
   </li>
   <li>
      childView0.model.name
   </li>
     .
     .
     .
   <li>
      childViewN.model.name
   </li>
</ul>

事实上,这是CompositeView首先构建的原因之一,请参阅Composite Views: Tree Structures, Tables, And More,参见网格视图部分。