5

起始问题

我有一个 CompositeView (一个表),集合中的每个模型都表示为两个表行,模板如下:

<tr class="row-parent">
    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>
</tr>

使用这样的 ItemView:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl
});

尽管它们被命名为“父”和“子”,但它们实际上是同一模型的对等成员。如果我没有指定 tagName,Backbone 会将每个视图包装在一个<div>既无效的 HTML 中,又会破坏布局。

首次尝试解决方案

所以我想,为什么不删除外部<tr>标签并让 Backbone 添加它们。所以我将模板更新为:

    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>

并将视图更新为:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tr',
    className: 'row-parent'
});

我希望外部标签能与内部标签片段结合,但 Marionette 不喜欢这样。它只显示了row-child。所以我不确定从这里去哪里。我正在考虑两种策略,但还没有详细说明。

前进:A计划

覆盖 Backbone 的任何部分创建额外的 div 以不创建它,或覆盖 Marionette 附加视图的部分以在附加之前删除 div。

前进:B计划

创建一种名为 CompositeMultiView 的新视图类型,它自然会扩展 CompositeView 并允许您指定第二个 ItemView,或者可能只是一个视图数组,所有这些都将为给定的每个模型呈现。这个计划似乎需要更多的工作,但更少被黑客入侵。


对于我将如何实施上述两个计划中的任何一个,是否有人有任何更好的建议、解决方法或具体指示?

这是表格应该是什么样子的模型: 在此处输入图像描述

4

3 回答 3

4

我一直在为同样的问题苦苦挣扎,直到今天我终于发现,一个表可以有多个tbody标签,每个标签都包含多个tr标签。

这实际上是为类似的主干问题提供的答案。

所以你ItemView会变成:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tbody'
});

和生成的html:

<table>
  <!-- first item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  <!-- second item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  ...
</table>
于 2015-06-12T04:10:10.143 回答
1

您可以尝试修改 CompositeView 如下:

  1. 指定itemView为视图数组
  2. 覆盖addChildView以呈现每个模型的每个视图

这个解决方案最终看起来很像你的“B计划”。试一试:

itemView: [My.ParentView, My.ChildView],

addChildView: function(item, collection, options){
  this.closeEmptyView();
  var itemViews = this.getItemView(item);
  var index = this.collection.indexOf(item);

  _.each(itemViews, function(ItemView) {
    this.addItemView(item, ItemView, index);
  });
}

我还没有考虑过这是否会处理模型事件,例如destroy,但我相信它应该优雅地处理它们。

于 2013-09-09T17:37:30.103 回答
0

肮脏的解决方案:向您的 ItemView 添加自定义渲染功能

// Or whatever template you use
var template = Handlebars.compile(datepickerTemplate);

var ItemView = Backbone.Marionette.ItemView.extend({
    render: function(){
        var html = template(this.model.toJSON());
        var newElement = $(html);
        this.$el.replaceWith(newElement);
        this.setElement(newElement);
        return this;
    }
});

这应该删除额外的 div 包装

于 2013-09-09T18:03:29.147 回答