在主干中渲染集合模型

Posted

技术标签:

【中文标题】在主干中渲染集合模型【英文标题】:Render Collection model in backbone 【发布时间】:2015-03-13 16:10:19 【问题描述】:

通常在为 Collection(s) 设计视图时,我会将collection 绑定到视图,并将相关事件注册到collection,如下所示:

var Book = Backbone.Model.extend();

var BookList = Backbone.Collection.extend(
    model: Book,
    url: "/books"
);

var BookListItemView = Backbone.View.extend(
    mtemplate: _.template($('#tpl_book_item').html()),
    render: function () 
        this.$el = $(this.mtemplate(this.model.toJSON()));
        return this;
    
);
var BookListView = Backbone.View.extend(
    el: '#content',
    initialize: function () 
        this.listenTo(this.collection, 'add', this.render);
        this.listenTo(this.collection, 'remove', this.render);
    ,
    render: function () 
        this.$el.empty();
        this.collection.each(function (item) 
            this.$el.append(new BookListItemView(model: item).render().$el);
        , this);
        return this;
    
);


Use:

    var books = new BookList();
    var bookListView = new BookListView(
        collection: books
    );
    books.fetch();

它按预期工作:按照模板中的定义渲染每本书。但是我发现页面有一点卡住。

我不确定这是否是由重新渲染视图引起的?如图所示,当books.fetch完成后,会将书籍添加到books的集合中,对于每一个book项目,都会触发一个add事件,然后我会通过删除exist重新渲染页面项并迭代集合。

这意味着一旦有 10 本书,BookListView 就会有 1+2+3+4...+10 循环。

我的意见,一旦add事件触发,我不应该刷新整个列表,而只是为BookListView添加一个新视图,但是remove事件呢,似乎Backbone不提供任何从模型中获取视图的内部方法,所以一旦模型被移除,我就无法获取相关视图。

你如何处理这种西装?

【问题讨论】:

【参考方案1】:

不要将您的add 绑定到render 函数。而是为此创建一个专用的 add 方法。

var Book, BookList, BookListItemView, BookListView;

Book = Backbone.Model.extend();

BookList = Backbone.Collection.extend(
  model: Book,
  url: "/books"
);

BookListItemView = Backbone.View.extend(
  mtemplate: _.template($("#tpl_book_item").html()),
  initialize: function() 
    this.model.on("remove", this.remove);
  ,
  render: function() 
    this.$el = $(this.mtemplate(this.model.toJSON()));
    return this;
  
);

BookListView = Backbone.View.extend(
  el: "#content",
  initialize: function() 
    this.listenTo(this.collection, "add", this.addItem);
  ,
  render: function() 
    this.$el.empty();
    this.collection.each((function(item) 
      this.addItem(item);
    ), this);
    return this;
  ,
  addItem: function(item) 
    this.$el.append(new BookListItemView(
      model: item
    ).render().$el);
  
);

让模型自己的 View 处理自己的删除事件。

【讨论】:

Let the models own View handle its own remove event +1,我从来没想过,谢谢。 谢谢。我还没有完全测试上面的代码,你可能需要改变一些东西。

以上是关于在主干中渲染集合模型的主要内容,如果未能解决你的问题,请参考以下文章

为父级调用渲染的主干子视图

过滤主干集合返回一个模型数组

模型属性未统一命名的主干集合和模板

View的主干变化模型

如何使用模型/集合获取 4 个 JSON (API) 响应到主干.js 中的一个视图

提取后新保存的 Backbone 模型未出现在集合中