CompositeView and/or CollectionView 不会呈现 table headers

CompositeView and/or CollectionView won't render table headers

我在复合视图或 collection 视图中呈现 headers 时遇到一些问题。我都试过了,但这根本无法呈现。

让我向您展示一下我的代码:

// composite view
define(function(require) {

    var BusinessTableTemplate = require("text!templates/BusinessTableTemplate.html");
    var BusinessRowView = require("views/BusinessRowView");
    var Marionette = require("marionette");

    return BusinessTableView = Marionette.CompositeView.extend({

        tagName: "table",
        className: "table table-hover",
        template: BusinessTableTemplate,
        itemView: BusinessRowView,
        appendHtml: function(collectionView, itemView){
            collectionView.$("tbody").append(itemView.el);
        }

    });

});

// BusinessTableTemplate
<script type="text/template">

    <thead>
        <tr>
            <th>Name</th>
            <th>Address</th>
            <th>Building</th>
            <th>Phone</th>
            <th>Website</th>
            <th>Categories</th>
        </tr>
    </thead>
    <tbody></tbody>

</script>

// itemview
define(function(require) {

    var BusinessRowTemplate = require("text!templates/BusinessRowTemplate.html");
    var Marionette = require("marionette");

    return BusinessRowView = Marionette.ItemView.extend({

        template: BusinessRowTemplate,
        tagName: "tr"

    });

});

// BusinessRowTemplate
<script type="text/template">

    <td>
        <%= name %>
    </td>
    <td>
        <% if (address) { %>
            <%= address %>
        <% } else { %>
            NA
        <% } %>
    </td>
    <td>
        <% if (building) { %>
            <%= building %>
        <% } else { %>
            NA
        <% } %>
    </td>
    <td>
    <td>
        <% _.each(phones, function(phone) { %>
            <span class="label label-default label-info"><%= phone %></span>
        <% }); %>
    </td>
    <td>
        <% if (website) { %>
            <%= website %>
        <% } else { %>
            NA
        <% } %>
    </td>
    <td>
        <% _.each(tags, function(category) { %>
            <span class="label label-default label-info"><%= category %></span>
        <% }); %>
    </td>
    <td>
        Ações
    </td>
</script>


// signal or event where I render the view
vent.on("search:seeAll", function(){
  if (self.results) {
    var businessDirectoryView = new BusinessDirectoryView();
    self.layout.modals.show(businessDirectoryView);
    var resultCollection = new Businesses(self.results, {renderInMap: false});
    var businessTableView = new BusinessTableView({
      collection: resultCollection
    });
    $("#businesses-container").html(businessTableView.render().$el);
  }
});

我按照某处的教程进行操作,但他们没有为 table 指定 headers。

对渲染这个有一点帮助吗?

谢谢!

您使用的 Marionette JS 版本是什么?

这是一个使用版本 2.4.1(最新可用)的 fiddle,它正在运行:

https://jsfiddle.net/aokrhw1w/2/

复合视图与之前的版本有一些变化,'itemView'更改为'childView'。

var BusinessTableView = Marionette.CompositeView.extend({
   tagName: "table",
   className: "table table-hover",
   template: '#BusinessTableTpl',
   childView: BusinessRowView,
   childViewContainer: "tbody",
   appendHtml: function (collectionView, itemView) {
                console.log('append');
                 this.$("tbody").append(itemView.el);
   }
});

希望这能解决您的问题。

CollectionView 在 collection 中为每个模型呈现一个 child 视图。它没有给你任何方法来添加额外的 HTML 就像 header.

CompositeView 也呈现 collection 项,但您也可以添加额外的 HTML。您的示例使用 CompositeView,因此您的选择是正确的。

因为您可以在呈现的 collection 周围自定义 HTML,您需要告诉 Marionette 在何处呈现 collection 项目视图。 childViewContainer 属性 这样做:

Marionette.CompositeView.extend({
    tagName: "table",
    className: "table table-hover",
    template: BusinessTableTemplate,
    itemView: BusinessRowView,
    childViewContainer: 'tbody'
});

对于像这样的简单情况,您不需要使用 attachHtml - 它适用于您需要更改 Marionette 的默认行为的边缘情况。

有关详细信息,请参阅 CompositeView docs

Marionette 3 弃用了 CompositeView class。相反,一个区域现在可以用渲染的内容覆盖它的 el new replaceElement option.

的内部视图

参见 this example 渲染 table:

var RowView = Marionette.View.extend({
  tagName: 'tr',
  template: '#row-template'
});

var TableBody = Marionette.CollectionView.extend({
  tagName: 'tbody',
  childView: RowView
});

var TableView = Marionette.View.extend({
  tagName: 'table',
  className: 'table table-hover',
  template: '#table',

  regions: {
    body: {
      el: 'tbody',
      replaceElement: true
    }
  },

  onRender: function() {
    this.showChildView('body', new TableBody({
      collection: this.collection
    }));
  }
});

var list = new Backbone.Collection([
  {id: 1, text: 'My text'},
  {id: 2, text: 'Another Item'}
]);

var myTable = new TableView({
  collection: list
});

myTable.render();

注意过分热心的版主:我给出了相同的答案 here. Both questions are not duplicates but do refer to the same deprecated class. It makes no sense to spend time to "tailor the answer to both questions”;这只是浪费时间,因为唯一重要的部分是:"This class is deprecated, use that one instead. Here's an example and link to the doc".