【问题标题】:Marionette-Backbone how do I make a grid table with a dynamic row and column headersMarionette-Backbone 如何制作带有动态行和列标题的网格表
【发布时间】:2015-02-21 23:27:20
【问题描述】:

我正在尝试使用木偶制作一个具有动态行数和列数的表格网格,并带有标题。

我想要一个看起来像这样的网格:http://jsfiddle.net/zaphod013/c3w61gf6/

所以有

columns = ['早餐', '午餐', '晚餐']

rows = ['carbs', 'proteins', 'fats']

网格的其余部分是复选框。

我已经为列和行创建了视图,但是我对如何将它们放入表中以及如何添加复选框视图感到很困惑。

我的代码是http://jsfiddle.net/zaphod013/qkctrLxn/

html:

<div id="main-region"></div>

<script id="food-table" type="text/template">
    <thead id="column-id">
    </thead>
    <tbody id="row-id">
    </tbody>
</script>

<script id="food-col-item" type="text/template">
    <th><%= col %></th>
</script>

<script id="food-row-item" type="text/template">
    <td><%= row %></td>
</script>

script:

FoodManager = new Backbone.Marionette.Application();

FoodManager.addRegions({
    mainRegion: "#main-region",
});

FoodManager.FoodLayout = Backbone.Marionette.Layout.extend({
    template: "#food-table",

    regions: {
       colRegion:"#column-id",
       rowRegion:"#row-id"
    }
});

FoodManager.Col = Backbone.Model.extend({});

FoodManager.ColCollection = Backbone.Collection.extend({
                                    model: FoodManager.Col
                                });

FoodManager.Row = Backbone.Model.extend({});

FoodManager.RowCollection = Backbone.Collection.extend({
                                    model: FoodManager.Row
                                });

FoodManager.ColItemView = Marionette.ItemView.extend({
    template: "#food-col-item",
    tagName: "th",
});

FoodManager.ColView = Marionette.CompositeView.extend({
    template: "#food-table",
    tagName: "thead",
    itemView: FoodManager.ColItemView
});

FoodManager.RowItemView = Marionette.ItemView.extend({
    template: "#food-row-item",
    tagName: "th",
});

FoodManager.RowView = Marionette.CompositeView.extend({
    template: "#food-table",
    tagName: "table",
    itemView: FoodManager.RowItemView
});

FoodManager.on("initialize:after", function(){
    var columns = new FoodManager.ColCollection([
                    {col: 'Breakfast'},
                    {col: 'Lunch'},
                    {col: 'Dinner'}
            ]);
    var rows = new FoodManager.RowCollection([
                    {row: 'Carbs'},
                    {row: 'Protein'},
                    {row: 'Fats'}
            ]);
    var colListView = new FoodManager.ColView({
                            collection: columns
                        });
    var rowListView = new FoodManager.RowView({
                            collection: rows
                        });
    var foodLayout = new FoodManager.FoodLayout();    
    foodLayout.render();
    FoodManager.colRegion.show(colListView);
    FoodManager.rowRegion.show(rowListView);

    FoodManager.mainRegion.show(foodLayout);

});

 FoodManager.start();

我将非常感谢一些关于如何解决此问题的建议。

感谢您的通读。

【问题讨论】:

  • “动态的行数和列数”是什么意思?你所描述的对我来说似乎不是动态的。动态意味着每次呈现表格时可能会有不同的数字,具体取决于您加载的数据。据我了解,您想要的表格总是三列三行。
  • html 示例显示 3 行 3 列作为渲染示例。但是如果你看 js 代码,行和列是集合,因此是动态的。
  • 作为建议,构建在另一个已经有坚实基础的框架之上。我在使用 BackgridJS 做类似事情时有很好的经验:backgridjs.com。列被描述为模型属性;行只是模型。单元格的渲染非常灵活。 Backgrid 的核心组件是可扩展的,甚至是可替换的。
  • 听起来您正在寻找的是一个需要多个集合的 CompositeView。不幸的是,目前 Marionette 库中不提供该功能。您的 HTML 不会验证,但您可以使用 LayoutView 执行您建议的操作。如果您需要帮助,请告诉我。
  • @Seebiscuit,我确实需要一些有关布局的帮助。我无法超越这个阶段。我想我在这里遗漏了一些关键概念。

标签: javascript backbone.js marionette


【解决方案1】:

这个答案有两个部分。首先,我建议您使用LayoutViewCollectionViews,因为您不需要集合本身的模板(不过,您仍将使用ItemView 模板)。其次,您必须让您的 Row 视图知道您需要多少复选标记列(这将是微不足道的),我们必须在 Row 视图中创建这些列.

加载您的LayoutView

您的FoodLayout 视图和模板非常完美。你奠定了基础。您需要使用两个 CollectionView 视图填充它:

FoodManager.ColItemView = Marionette.ItemView.extend({
    template: "#food-col-item",
    tagName: "th",
});

FoodManager.ColView = Marionette.CollectionView.extend({
    itemView: FoodManager.ColItemView
});

FoodManager.RowItemView = Marionette.ItemView.extend({
    template: "#food-row-item",
    tagName: "tr",
});

FoodManager.RowView = Marionette.CollectionView.extend({
    itemView: FoodManager.RowItemView
});

请注意,我将您的CompositeView 更改为CollectionView,并将ItemView 中的tagName 更改为tr,用于Row 视图。 (注意:您要删除#food-col-item 中的&lt;th&gt; 标签,Backbone 会为您生成它们。)

Row 视图中生成动态列

现在有趣的部分来了。我们将使用templateHelpers 在您的Row 视图中创建复选标记行。如果您查看docstemplateHelpers 是一个哈希值,可让您在渲染之前向模板添加数据。 “数据”或 JavaScript 对象可以是函数(因为函数是 JavaScript 中的第一类对象)。所以,我们将使用templateHelpers 传递我们需要复选标记的食物列,并组合一个函数,该函数将食物列作为参数,并返回用于这些检查的 html -标记列。

将此templateHelpers 属性放在您的'FoodManager.FoodLayout 视图中:

templateHelpers: function () {
  return {
    foods: function () {
      return this.foodColumns
    },

    addColumns: function (foodcols) {
      var html = '';
       for (food in foodcols)
         html += "<td><input type="checkbox" class=" + 
                    food + "-check"></td>";

       return html;
    }
  }
} 

您的Row 模板将如下所示:

<script id="food-row-item" type="text/template">
    <td><%= row %></td><% addColumns(foods) %>
</script>

您需要注意的是,您需要将您用于ColCollection 的食物列提供给FoodManager.FoodLayout,以便您可以填充this.templateHelpers.foods。有多种方法可以将其放入其中。我只是使用this.foodColumns 作为虚拟占位符。

【讨论】:

  • 非常感谢您的详细解释。我可以让它工作。我所做的唯一更改是在 rowCollectionView 而不是 Layout 中传递 foodColumns。
  • 这是工作版本,供参考:jsfiddle.net/zaphod013/mg3xcx5h
  • 几件事: 1.(次要)serializeData 做了 templateHelpers 试图做的一个主要区别,this 内部 serializeData 是视图,而 this 内部templateHelpers` 是 dataserializeData 混合在一起的。如果您看一下小提琴,我删除了templateHelpers 中的food 属性,并留下了覆盖的serializedData。 3.(次要)我在您的ColView 中添加了tr。这将替换视图的边界 div,让 Bootstrap 完成它的工作。
  • 3. (主要)不幸的是,对于RowView 中的边界div,没有简单 解决方法。您可以将行直接附加到区域。我想出了一个解决方法,但我还没有对它进行广泛的测试。这是实现它的答案的链接:stackoverflow.com/a/27473851/2112866。这是包含前两项的更新小提琴的链接:jsfiddle.net/mg3xcx5h/2
  • 我申请了3。请仔细研究一下,有很大的变化,尤其是它使用了当前的Mn版本(2.4.0)。这会将itemView 更改为childView,并将Layout 更改为LayoutView。在这里查看小提琴:jsfiddle.net/Seabiscuit/azmww8dg/1
猜你喜欢
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2023-03-12
  • 2013-01-15
  • 1970-01-01
相关资源
最近更新 更多