我认为我不太了解正确使用Backbone路由器背后的想法。这就是我所拥有的:
我有一些数据,我在页面加载时从服务器获取数据,然后将其打包到模型和集合中。这些模型和集合的数量是无限的。我想使用路由器直接从一开始就呈现某个集合的视图。
问题是:Backbone路由器提前启动,因为我要求它访问某个视图并触发其render
操作,所以它不能这样做,因为这些视图尚未创建。这意味着我实际上必须在获取完成后启动我的路由。
我不知道这是否是一种正确的方法,但我想出的唯一想法是:
Backbone.history.start();
位包装到单独的顶级可访问功能中(即稍后准备手动调用)。success
fetch()
回调
_.defer()
和_.once()
。这很有效,但看起来很奇怪:
路由器:
window.startRoutes = _.once(function() {
var AccountPage = Backbone.Router.extend({
routes: {
'set/:id': 'renderSet',
},
renderSet: function(setId) {
/** … **/
// Call the rendering method on the respective CardView
CardsViews[setId].render();
}
});
var AccountPageRouter = new AccountPage;
Backbone.history.start();
});
收集:
window.CardsCollection = Backbone.Collection.extend({
model: Card,
initialize: function(params) {
/** … **/
// Get the initial data
this.fetch({success: function() {
_.defer(startRoutes);
}});
},
});
所以我的问题是......我做得对吗?或者有更好的方法(必须)吗?
答案 0 :(得分:14)
您可以提前定义路由器;在你调用Backbone.History.start()之前,它不会做任何事情。
你可以绑定"重置"您的收藏中的活动可以像这样开始历史记录:
my_collection.bind("reset", _.once(Backbone.History.start, Backbone.History))
然后,当您的集合完全加载时,路由器将开始执行操作。我不确定这是否正是您正在寻找的(因为您提到了可变数量的集合)。
我有类似的情况,除了我事先知道在开始路由之前我想要加载哪些集合。我在我的路由器上添加了一个startAfter方法,如下所示:
window.Workspace = new (Backbone.Router.extend({
. . .
startAfter: function(collections) {
// Start history when required collections are loaded
var start = _.after(collections.length, _.once(function(){
Backbone.history.start()
}))
_.each(collections, function(collection) {
collection.bind('reset', start, Backbone.history)
});
}
}));
然后我设置了我的收藏品
Workspace.startAfter([collection_a, collection_b, ...])
这也可以适用于独立模型,虽然我认为您需要绑定到“重置”之外的其他模式。事件
我很高兴我阅读了您的示例代码,使用_.once和_.defer指出了我正确的方向。
答案 1 :(得分:1)
我只是在使用它之前检查我的.render()
方法是否填充了所有必填字段。如果它尚未填充 - 我正在呈现'正在加载... '小部件。
我的所有观看次数都按照this.model.bind('change', this.render, this);
订阅了模型更改,因此在加载模型后,将再次调用render()
。