Backbone:如何在集合更改时更新集合视图?

Ale*_*x B 9 javascript backbone.js backbone-events backbone.js-collections

我对Backbone.js比较陌生.我正在初始化一个集合视图并在创建时传入一个集合.

suggestionsView = new TreeCategoriesAutoSuggest.Views.Suggestions({
    collection: new App.Collections.Suggestions(this.getSuggestions(query))
});
Run Code Online (Sandbox Code Playgroud)

然后我渲染集合视图.每次用户在文本框中输入查询时,都会重新生成集合并使用以下内容将其分配给集合视图:

suggestionsView.collection.set(this.getSuggestions(query));
Run Code Online (Sandbox Code Playgroud)

这样可以处理集合中模型的添加/删除,但如何管理添加/删除模型的视图添加/删除?

我应该提一下,我在集合视图中使用了this.collection.on("add")侦听器.但是这会被添加到每个模型中.我也在单个视图中尝试过this.model.on("更改"),但是当从集合中添加/删除模型时,不会触发此操作.

任何帮助/指导赞赏!

更新

我现在正在使用:

suggestionsView.collection.reset(this.getSuggestions(query));
Run Code Online (Sandbox Code Playgroud)

当重置事件被触发时,我正在删除建议子视图,为新集合重新初始化它们并重新呈现集合视图.

handleReset: function(){
    console.log("reset");
    this.cleanupOldViews();
    this.initViews();
},

initViews: function(){
    this.collection.each(function(suggestion){
        this.suggestionViews.push(new TreeCategoriesAutoSuggest.Views.Suggestion({
            model: suggestion
        }));
    },this);        
},

cleanupOldViews: function(){
    _.each(this.suggestionViews,function(suggestionView){
        suggestionView.remove()
    },this);

    this.suggestionViews = [];
}
Run Code Online (Sandbox Code Playgroud)

所以你认为我不需要担心破坏模型?

mu *_*ort 16

使用reset以下方法可以更轻松,更高效地批量更换:

重启 collection.reset([models], [options])

一次添加和删除模型一切都很好,但有时你需要改变很多模型,而不是只是批量更新集合.使用reset将集合替换为新的模型列表(或属性哈希值),最后触发单个"reset"事件.返回新设置的模型.为方便起见,在一个"reset"事件中,任何以前的模型列表都可用options.previousModels.

因此,而不是使用set合并的变化,产生了一堆'add''remove'事件,利用reset和监听'reset'事件:

// In the view's `initialize`...
this.listenTo(this.collection, 'reset', this.render);
Run Code Online (Sandbox Code Playgroud)

然后render可以重绘整个事情,你会说:

suggestionsView.collection.reset(this.getSuggestions(query))
// ------------------------^^
Run Code Online (Sandbox Code Playgroud)

刷新东西.


评论中的一些澄清:模型不生成'add'事件,只有集合触发那些.模型'change'在属性发生变化时触发事件,集合触发器'add''remove'事件(分别)从模型中添加和删除模型时触发事件; 集合也可以触发'change'事件,因为它们从封闭的模型中转发所有事件:

为方便起见,也会在集合中直接触发在集合中的模型上触发的任何事件.

因此,如果您想使用,Collection#set那么您需要在视图中使用三个处理程序:

  1. this.listenTo(this.collection, 'add', ...):已将新模型添加到集合中以进行渲染.
  2. this.listenTo(this.collection, 'remove', ...):已从集合中删除模型,因此删除其视图的一部分.
  3. this.listenTo(this.collection, 'change', ...):模型已更改,因此更新其视图的一部分.

如果您只使用小型馆藏,那么reset可能会减少工作量.如果您的集合较大或视图更改更昂贵,那么单独处理这三个事件可能是最好的.

在任何情况下,如果您正在使用子视图,您将需要在父视图中的某个位置维护它们的列表,以便您可以调用remove它们以确保正确清理事物.如果您在从集合中删除模型时销毁模型,则可以将子视图绑定到模型的'destroy'事件并根据需要删除它们.

活动的目录可能是值得一看在何时被触发什么事件回顾.