调试Backbone.js:在collection fetch()之后进行渲染

时间:2012-11-27 06:55:33

标签: backbone.js

我正在尝试在集合上的fetch()之后执行基本的render()(Backbone 0.9.2):

var ProjectListView = Backbone.View.extend({
        el: $('#container'),
        initialize: function () {
            this.collection = new ProjectsCollection();
            this.collection.bind("change", _.bind(this.render, this));
            this.collection.fetch({ success: function () { console.log("collection fetched"); } });
            ...
             }, 
        render: function () {
            console.log("rendered");
            ...

创建新的View实例打印出来:

    collection fetched 

因此在fetch()之后永远不会调用render()。我在这做错了什么?没有例外。

如何在骨干网中调试这些东西?

聚苯乙烯。 考虑到SO上的问题数量,似乎这个特征记录很差。

3 个答案:

答案 0 :(得分:29)

来自fine manual

  

抓取 collection.fetch([options])

     

从服务器获取此集合的默认模型集,在集合到达时重置集合。 [...]当模型数据从服务器返回时,集合将重置。

reset做了什么? reset这样做:

  

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

     

[...]使用重置将集合替换为新的模型列表(或属性哈希值),最后触发单个"reset"事件。

因此fetch调用reset来更新集合的模型,reset触发"reset"事件,而不是"change"事件。没有一个模型发生变化,集合的"change"事件来自其模型。

您应该render绑定到"reset"

initialize: function () {
    this.collection = new ProjectsCollection();
    this.collection.bind("reset", _.bind(this.render, this));
    this.collection.fetch(...);
}

如果您想在所包含的模型上侦听"change"事件,那么您可以将"change"处理程序绑定到集合since

  

您可以绑定"change"个事件,以便在修改集合中的任何模型时收到通知   [...]
  为方便起见,也会直接在集合中触发在集合中的模型上触发的任何事件。

当集合本身发生变化时,该集合还会生成"add""remove"个事件。


较新版本的Backbone不再在fetch期间重置集合:

  

当模型数据从服务器返回时,它使用 set 来(智能地)合并获取的模型,除非你通过{reset: true},在这种情况下集合将(有效地) 重置

set

  

[...]使用传递的模型列表对集合执行“智能”更新。如果列表中的模型尚未包含在集合中,则会添加该模型;如果模型已经在集合中,则其属性将被合并;如果集合包含列表中不存在的任何模型,它们将被删除。发生这种情况时会触发所有相应的"add""remove""change"事件

因此,对于较新版本的Backbone,您需要列出"add""remove""change"事件(基于集合的视图应该监听的事件);您也可以在初始{reset: true}上使用fetch,也可以收听"reset"。我建议基于集合的视图使用以下方法:

  1. 听取"add"并使用回调来处理该事件,该回调只是将一个项目添加到视图中,不要丢弃所有内容并重新渲染。
  2. 收听"remvoe"并使用仅删除新移除的模型的回调来处理该事件。
  3. 收听"change"并使用可替换(或更新)相应项目的回调来处理该问题。
  4. 收听"reset"并将其绑定到render。然后将{reset: true}传递给集合的初始fetch电话。
  5. 这将捕获重要事件,而集合视图将执行最少量的工作来处理每个事件。当然,这种策略不适用于所有情况,但我认为这是一个很好的起点。

答案 1 :(得分:8)

这在1.0中改变了

http://backbonejs.org/#changelog

“如果您想继续使用”重置“,请通过{reset:true}。”

答案 2 :(得分:3)

好的,直到某人能解释为什么绑定不起作用,我使用了以下解决方法:

   initialize: function () {
            var self = this;
            this.collection = new ProjectsCollection();
            this.collection.fetch({ success: function () { self.render(); } });