我正在尝试在集合上的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");
...
Run Code Online (Sandbox Code Playgroud)
打印出新的View实例:
collection fetched Run Code Online (Sandbox Code Playgroud)
因此,在fetch()之后永远不会调用render().我在这做错了什么?没有例外.
如何在骨干中调试这些东西的任何提示?
PS.考虑到SO上的问题数量,似乎这个特征记录很差.
mu *_*ort 29
从精细手册:
取
collection.fetch([options])从服务器获取此集合的默认模型集,在集合到达时重置集合.[...]当模型数据从服务器返回时,集合将重置.
那怎么reset办?reset做这个:
重启
collection.reset(models, [options])[...]使用reset将集合替换为新的模型列表(或属性哈希值),最后触发单个
"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(...);
}
Run Code Online (Sandbox Code Playgroud)
如果要监听"change"包含模型上的事件,则可以将"change"处理程序绑定到集合,因为:
您可以绑定
"change"事件,以便在修改集合中的任何模型时收到通知,
[...]
为方便起见,也会在集合中直接触发集合中模型触发的任何事件.
该集合还将在集合本身发生变化时生成"add"和生成"remove"事件.
较新版本的Backbone在以下期间不再重置集合fetch:
当模型数据从服务器返回时,它使用set来(智能地)合并获取的模型,除非你通过
{reset: true},在这种情况下集合将被(有效地)重置.
而且set:
[...]使用传递的模型列表对集合执行"智能"更新.如果列表中的模型尚未包含在集合中,则会添加该模型; 如果模型已经在集合中,则其属性将被合并; 如果集合包含列表中不存在的任何模型,它们将被删除.发生这种情况时,会触发所有相应的
"add","remove"和"change"事件
因此,与骨干网的新版本,你会希望列出的"add","remove"和"change"事件(集合基于视图应该倾听反正); 你也可以{reset: true}在初始时使用fetch并听取"reset".我建议基于集合的视图使用以下方法:
"add"使用回调来监听和处理该事件,该回调只是向视图添加一个项目,不要丢弃所有内容并重新渲染."remvoe"使用仅删除新删除的模型的回调来侦听和处理该事件."change"使用可替换(或更新)相应项的回调来监听和处理."reset"并将其绑定到render.然后传递{reset: true}给集合的初始fetch调用.这将捕获重要事件,集合视图将执行最少量的工作来处理每个事件.当然,这种策略不适用于所有情况,但我认为这是一个很好的起点.