我正在尝试在集合上的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上的问题数量,似乎这个特征记录很差。
答案 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"
。我建议基于集合的视图使用以下方法:
"add"
并使用回调来处理该事件,该回调只是将一个项目添加到视图中,不要丢弃所有内容并重新渲染。"remvoe"
并使用仅删除新移除的模型的回调来处理该事件。"change"
并使用可替换(或更新)相应项目的回调来处理该问题。"reset"
并将其绑定到render
。然后将{reset: true}
传递给集合的初始fetch
电话。这将捕获重要事件,而集合视图将执行最少量的工作来处理每个事件。当然,这种策略不适用于所有情况,但我认为这是一个很好的起点。
答案 1 :(得分:8)
答案 2 :(得分:3)
好的,直到某人能解释为什么绑定不起作用,我使用了以下解决方法:
initialize: function () {
var self = this;
this.collection = new ProjectsCollection();
this.collection.fetch({ success: function () { self.render(); } });