Backbone.js 路由器初始化不会立即运行
Posted
技术标签:
【中文标题】Backbone.js 路由器初始化不会立即运行【英文标题】:Backbone.js Router initialization doesn't run immediately 【发布时间】:2012-05-07 23:04:09 【问题描述】:我的代码如下:
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
函数中为空。我必须在$.ajax success
回调函数的底部使用self._index.render()
来渲染主页(上面已注释掉)。 index
函数似乎在 initialize
函数之前运行。这怎么会发生,我该如何解决?
顺便说一句,在routes
中,如果我使用"": "index"
,它将不起作用。我必须使用"*action": "index"
。但我在其他地方了解到默认 url 可能只是空字符串。为什么我不能在这里使用它?
【问题讨论】:
【参考方案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();
,
您还需要设置您的集合以构建适当的 URL 来请求 data/todolist.json
。
【讨论】:
在你的代码中,我认为self._todos = new TodosCollection(data);
应该是self._todos = new TodosCollection();
,对吧?【参考方案2】:
确实,这里的问题是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
。显然你不需要在initialize中再次调用ajax,直接使用options中传入的数据即可。
【讨论】:
谢谢伙计,它现在可以工作了。还有一个问题,"category/:name": "hashcategory"
路由似乎永远不会触发。我的 html 中有一个 <a>
link,其中有 'href='#/category/num1'
attribute。但每次我点击它时,url 都会改变,但没有其他任何反应。我在hashcategory
方法中有一个console.log('started')
,但它什么也没打印。你知道为什么吗?【参考方案3】:
您的问题是路线的顺序。路由按顺序进行评估,因此“*action”将始终匹配。
试试:
routes:
"category/:name": "hashcategory"
"*action": "index",
【讨论】:
以上是关于Backbone.js 路由器初始化不会立即运行的主要内容,如果未能解决你的问题,请参考以下文章