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

Insert rendered view after base element

所以我有一个 compositeView。 CompositeView 是一个 "ul" 元素,第一个 "li" 元素和另一个 "li" 元素的集合。我的 objective 是在基础 "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'}
]}
...
] 

更新问题:

由于 Backbone.View 生成的视图包装器,无法准确获得您的结构 want.You 最多只能有多个 li,每个 li 具有 li(基础)和兄弟 li(集合) 项目,但它们将存在于二级列表中。像这样,

<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 上的模板将return

<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,参见 Grid Views 部分。

我认为问题的核心是您提出的结构无效 HTML。来自 MDN:

The HTML <li> element (or HTML List Item Element) is used to represent an item in a list. It must be contained in a parent element: an ordered list (<ol>), an unordered list (<ul>), or a menu (<menu>). In menus and unordered lists, list items are usually displayed using bullet points. In ordered lists, they are usually displayed with an ascending counter on the left, such as a number or letter.

当您嵌套 <li> 元素时,正确的结构是将列表的每个新级别都包装在 <ul> 中。

您应该为您的结构使用 div 或将嵌套的 <li> 包裹在 <ul> 中。

如果您选择更改结构,那么 Marionette 会更容易适应它。