2015-01-15 166 views
0

采集模型通常当收集(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事件,似乎骨干不提供任何内部方法来获得从模型来看,所以一旦模型被删除,我就无法得到相关的视图。

你如何处理这种诉讼?

回答

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); 
    } 
}); 

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

+0

'让模型自己的View处理自己的remove事件'+1,我从来没有想过,谢谢。 – hguser

+0

谢谢。我没有完全测试上面的代码,你可能需要改变一些东西。 – Exinferis