在骨干中渲染集合模型

时间:2015-01-15 09:40:13

标签: backbone.js

通常在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事件,然后我将重新开始通过删除存在的项目来渲染页面并迭代集合。

这意味着一旦有10本书,1+2+3+4...+10将有BookListView个圈。

我的意见是,一旦触发add事件,我就不应该刷新整个列表,而只是向BookListView添加一个新视图,但remove事件怎么样呢,它似乎Backbone没有提供任何内部方法来从模型中获取视图,因此一旦要删除模型,我就无法获得相关视图。

你如何处理这种诉讼?

1 个答案:

答案 0 :(得分:2)

不要将add绑定到render功能。而是为此创建一个专用的添加方法。

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处理自己的删除事件。