13

我了解如何将一个集合或单个模型组合在一起。而且我通常可以获得模型的数据来显示。但我根本不清楚如何获取一个集合并获取该集合中的模型列表以显示。

我应该迭代集合并单独渲染每个模型吗?这应该是集合的渲染功能的一部分吗?

还是集合只是有它自己的视图,并且我以某种方式将整个集合数据填充到视图中?

笼统地说,显示模型列表的正常方法是什么?

4

4 回答 4

13

根据我的经验,最好在集合视图中保留对每个模型视图的引用。

我目前正在处理的项目中的这个片段应该可以帮助你更好地理解这个想法:

var MyElementsViewClass = Backbone.View.extend({
    tagName: 'table',

    events: {
        // only whole collection events (like table sorting)
        // each child view has it's own events
    },
    initialize: function() {
        this._MyElementViews = {}; // view chache for further reuse
        _(this).bindAll('add');
        this.collection.bind('add', this.add);
    },
    render: function() {
        // some collection rendering related stuff
        // like appending <table> or <ul> elements

        return this;
    },
    add: function(m) {
        var MyElementView = new MyElementViewClass({
            model: m
        });

        // cache the view
        this._MyElementViews[m.get('id')] = MyElementView;

        // single model rendering
        // like appending <tr> or <li> elements
        MyElementView.render(); 
    }
});

采用这种方法可以更有效地更新视图(重新渲染表中的一行而不是整个表)。

于 2011-04-13T22:28:45.883 回答
8

我认为有两种方法可以做到这一点。

  • 每个项目使用一个视图,并自己操作 DOM。这就是 Todos 示例所做的。这是一种很好的处理方式,因为单个模型项的事件处理更加清晰。您还可以为每个项目制作一个模板。不利的一面是,您没有一个整体的集合视图模板。
  • 对整个集合使用视图。这里的主要优点是您可以在模板中进行更多操作。缺点是你没有每个项目的模板,所以如果你有一个异构的集合,你需要在集合视图模板代码中切换——乱七八糟的。

对于第二种策略,我完成了如下代码:

var Goose = Backbone.Model.extend({ });

var Gaggle = Backbone.Collection.extend({
   model: Goose;
};

var GaggleView = Backbone.View.extend({
    el: $('#gaggle'),
    template: _.template($('#gaggle-template').html()),
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
    }
};

var g = new Gaggle({id: 69);

g.fetch({success: function(g, response) {
    gv = new GaggleView({model: g});
    gv.render();
}});

模板代码如下所示:

  <script type="text/template" id="gaggle-template">
  <ul id="gaggle-list">
  <% _.each(gaggle, function(goose) { %>
     <li><%- goose.name %></li>
  <% }); %>
  </ul>
  </script>

请注意,我在模板中使用了 _ 函数(很有用!)。我还使用模板函数中捕获的“obj”元素。这可能有点作弊;传入 {gaggle: [...]} 可能会更好,并且更少依赖于实现。

我认为归根结底,答案是“有两种方法可以做到,但都不是那么好。”

于 2012-01-08T03:03:38.530 回答
3

主干的想法是视图渲染是事件驱动的。

视图附加到模型数据更改事件,因此当模型中的任何数据发生更改时,视图会自动为您更新。

您对集合的作用是同时操作模型集合。

我建议阅读带注释的示例

于 2011-04-13T15:34:12.650 回答
0

我还发现这是 Backbone 框架中令人困惑的部分。

示例 Todos 代码是此处的示例。它使用 4 个类:

  • Todo(扩展 Backbone.Model)。这表示要完成的单个项目。
  • TodoList(扩展 Backbone.Collection)。它的“模型”属性是 Todo 类。
  • TodoView(扩展 Backbone.View)。它的标记名是“li”。它使用模板来呈现单个 Todo。
  • AppView(扩展 Backbone.View)。它的元素是 "#todoapp" 。它没有一个“模型”属性,而是使用一个名为“Todos”的全局 TodoList(目前尚不清楚为什么......)。它绑定到 Todos 上的重要更改事件,当发生更改时,它要么添加一个 TodoView,要么循环遍历所有 Todo 实例,一次添加一个 TodoView。它没有用于渲染的单一模板;它让每个 TodoView 呈现自己,并且它有一个单独的模板来呈现统计区域。

这并不是世界上第一次审查的最佳例子。特别是,它不使用 Router 类来路由 URL,也不将模型类映射到 REST 资源。

但似乎“最佳实践”可能是为集合的每个成员保留一个视图,并直接操作由这些视图创建的 DOM 元素。

于 2012-01-08T02:33:54.577 回答