3

我的代码如下:

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();
    },
 ....

但是当我开始时,萤火虫控制台面板总是告诉我函数this._index中为空index。我必须self._index.render()在回调函数的底部使用$.ajax success才能使主页呈现(上面​​已注释掉)。似乎index函数在函数之前initialize运行。这怎么可能发生,我该如何解决?

顺便说一句,在 中routes,如果我使用"": "index",它将不起作用。我必须使用"*action": "index". 但我在其他地方了解到默认 url 可能只是空字符串。为什么我不能在这里使用它?

4

3 回答 3

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 });    
});

这将获取路由,然后使用它们初始化路由器以及 start Backbone.history。显然你不需要在初始化时再次进行ajax调用,只需使用选项中传递的数据即可。

于 2012-04-27T18:18:46.653 回答
1

看起来发生这种情况是因为 this._index 仅在 ajax 回调中设置。因为这是异步的,所以不能保证它会在索引事件处理程序触发之前执行。

根据文档,您在初始加载时需要的模型应该是 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

于 2012-04-27T11:34:59.540 回答
0

您的问题是路线的顺序。路由按顺序进行评估,因此“*action”将始终匹配。

尝试:

routes: {
  "category/:name": "hashcategory"
  "*action": "index",
}
于 2012-11-29T23:45:35.360 回答