【问题标题】:Backbone.js Router initialization doesn't run immediatelyBackbone.js 路由器初始化不会立即运行
【发布时间】: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._indexindex 函数中为空。我必须在$.ajax success 回调函数的底部使用self._index.render() 来渲染主页(上面已注释掉)。 index 函数似乎在 initialize 函数之前运行。这怎么会发生,我该如何解决?

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

【问题讨论】:

    标签: backbone.js backbone-routing


    【解决方案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",
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-27
      • 2015-01-12
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2012-11-10
      相关资源
      最近更新 更多