Backbone.js路由器初始化不会立即运行

时间:2012-04-27 07:31:43

标签: backbone.js backbone-routing

我的代码如下:

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"。但我已经在其他地方学到了默认网址可能只是空字符串。为什么我不能在这里使用它?

3 个答案:

答案 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",
}