【问题标题】:Backbone view el as table column主干视图 el 作为表格列
【发布时间】:2013-11-22 20:53:34
【问题描述】:

有没有人使用 Backbone.js 将垂直表格列用作视图“el”?由于表是基于行的,因此使用表行作为与视图关联的 DOM 容器很简单。但是,我需要实现的布局是垂直的,因此表格列将是我设计的“el”,但表格列没有类似的容器元素,因为表格布局是水平的。

到目前为止,我还不能成功地为表列创建子视图,这意味着我将数据绑定到我的 DOM 以便检索和操作表列。我的设计变得更加复杂,这导致我重新评估原始方法,希望有更好的方法通过子视图来管理这种情况。有什么想法吗?

【问题讨论】:

  • 您实际上是在呈现表格数据,还是使用表格进行布局?如果是后者——不要。 stackoverflow.com/questions/83073/…
  • 如果您的数据以符合垂直列格式的特定格式返回,这是可能的。显然,tbody 将是您的上下文,而重复的列是其中的元素。
  • 您的数据必须是多数组格式。例如,[[{'第一列第一行','第一列第二'}],[{4567,'第二列第一行','第二列第二行'}]]。对于每一列,循环遍历每个数组,直到到达列的末尾。
  • 这是真正的表格数据——它是一个产品比较屏幕,每一列是一个产品,每一行是产品的一个特定属性。我没有能力修改设计。我们需要能够实时从表中添加或删除产品,而 Backbone 非常适合,它只是杀死它的垂直布局。

标签: javascript backbone.js backbone-views


【解决方案1】:

你可以利用这个事实,

  • jQuery 对象是 DOM 元素的列表
  • Backbone 不需要唯一的 DOM 节点(至少据我所知)
  • this.$el 在视图中可以是你想要的任何节点

考虑到这一点,您可以一次性渲染您的表格(请参阅BackboneJS Rendering Problems,它更快,在您的情况下可能更容易),然后将您的子视图应用于与模型关联的表格单元格。我选择了一个类名,但每行的第 n 个元素上的选择器应该可以工作。

模板

<table>
    <thead>
        <tr>
            <th></th>
            <% _(children).each(function(model) { %>
                <th><%= model.id %></th>                
            <% }); %>
        </tr>
    </thead>
    <tbody>
    <% _(properties).each(function(prop) { %>
        <tr>
            <td><%= prop %></td>
            <% _(children).each(function(model) { %>
                <td class="<%= model.cid %>"><% print(model[prop]); %></td>
            <% }); %>
        </tr>
    <% }); %>
    </tbody>
 </table>

查看

ListView = Backbone.View.extend({
    initialize: function(opts) {
        this.options = opts;
    },
    render: function () {
        var data, html, $table, template = this.options.template;

        data = this.collection.map(function (model) {
            return _.extend(model.toJSON(), {
                cid: model.cid
            });
        });

        html = this.options.template({
            children: data,
            properties: ['id', 'name']
        });

        $table = $(html);

        this.collection.each(function (model, ix) {
            var $el = $table.find("." + model.cid),
                subview = new ItemView({
                    el: $el,
                    model: model
                });
        });

        this.$el.empty();
        this.$el.append($table);

        return this;
    }
});

您可以查看此演示 http://jsfiddle.net/nikoshr/psasT/12/,每一列都由一个专用视图处理。

【讨论】:

  • 哇,这是一种将“el”作为元素集合而不是单个元素来管理的相当优雅的方式——我确实想到了这一点,但我认为它不会起作用。我想我想采用类似这种解决方案的方法。
【解决方案2】:

我想不出一个简单的解决方案来解决您的问题。让多个视图共享&lt;table&gt; 元素,因为el 听起来像是一场潜在的噩梦。

如何从不同的角度解决问题,而不是使用 HTML 表格,用浮动的 &lt;div&gt; 元素构建表格列,并将视图绑定到这些元素?比如:

<div class="faux-table">
  <div class="faux-column">
    <div class="faux-header">Col 1</div>
    <div>Foo</div>
    <div>Bar</div>
    <div>Baz</div>
    <div>Qux</div>
  </div>
  <div class="faux-column">
    <div class="faux-header">Col 2</div>
    <div>Foo</div>
    <div>Bar</div>
    <div>Baz</div>
    <div>Qux</div>
  </div>
</div>

还有一个 CSS 规则:

.faux-table > div.faux-column {
    float:left;
}

this fiddle 中的工作示例。这个解决方案当然远非完美,因为如果你有可变大小的内容,你必须自己实现行大小。但是如果你需要获取Backbone视图渲染的表格,从JS的角度来看,这可能是最简单的方法。

编辑: 实际上,在我看来,一个更好且不那么脆弱的解决方案是使用表 &lt;td&gt; 元素作为列,并将行实现为 &lt;div&gt;s 而无需任何 CSS浮动黑客:

<table>
    <tr>
        <td class="faux-column">
            <div class="faux-header">Col 1</div>
            <div>Foo</div>
            <div>Bar</div>
            <div>Baz</div>
            <div>Qux</div>
        </td>
        <td class="faux-column">
            <div class="faux-header">Col 2</div>
            <div>Foo</div>
            <div>Bar</div>
            <div>Baz</div>
            <div>Qux</div>
        </td>
    </tr>
</table>

Revised version in this fiddle.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2012-10-18
    相关资源
    最近更新 更多