我的代码如下:
var AppRouter = Backbone.Router.extend({
_data: null,
_length: 0,
_index: null,
_todos: null,
_subtodolist: null,
_subtodos: null,
routes: {
"*action": "index",
"category/:name": "hashcategory"
},
initialize: function(options){
var self = this;
if (this._index === null){
$.ajax({
url: 'data/todolist.json',
dataType: 'json',
data: {},
success: function(data) {
self._data = data;
self._todos = new TodosCollection(data);
self._index = new CategoriesView({collection: self._todos});
//self._index.render();
}
});
return this;
}
return this;
},
index: function(){
this._index.render();
},
....
但是当我开始使用时,firebug控制台面板总是告诉我this._index
函数中的index
为空。我必须使用self._index.render()
回调函数底部的$.ajax success
来进行主页渲染(上面已注释掉)。似乎index
函数在initialize
函数之前运行。怎么会发生这种情况,我该如何解决?
顺便说一下,在routes
中,如果我使用"": "index"
,它将无效。我必须使用"*action": "index"
。但我已经在其他地方学到了默认网址可能只是空字符串。为什么我不能在这里使用它?
答案 0 :(得分:5)
这里的问题确实是initialize
在其内部的ajax调用解决之前返回。
您可以做的是在切入点执行以下操作(通常为$.ready()
)
var self = this,
p = $.ajax({
url: 'data/todolist.json',
dataType: 'json'
});
p.done(function (data) {
AppRouter = new Backbone.Router({data: data});
Backbone.history.start({ pushState: true });
});
这将获取路由,然后用它们初始化路由器以及启动Backbone.history
。显然你不需要在初始化时再次执行ajax调用,只需使用选项中传递的数据。
答案 1 :(得分:1)
看起来这是因为this._index只在ajax回调中设置。因为这是异步的,所以不能保证它会在索引事件处理程序触发之前执行。
根据文档,您在初始加载时需要的模型should be bootstrapped。
如果不可能,构建此代码的一种方法可能是在路由被命中时获取数据,并将重置事件绑定到您的视图,例如
var CategoriesView = Backbone.View.extend({
initialize: function() {
this.collection.on("reset", this.render);
},
...
var AppRouter = Backbone.Router.extend({
_index: null,
_todos: null,
routes: {
"": "index",
"category/:name": "hashcategory"
},
initialize: function(options){
var self = this;
self._todos = new TodosCollection();
self._index = new CategoriesView({ collection: self._todos });
},
index: function(){
this._todos.fetch();
},
您还需要设置您的收藏集,以构建适当的网址来请求data/todolist.json
。
答案 2 :(得分:0)
您的问题是路线的顺序。路由按顺序进行评估,因此“* action”始终匹配。
尝试:
routes: {
"category/:name": "hashcategory"
"*action": "index",
}