RequireJs:错误的模块订单

时间:2012-08-31 16:54:24

标签: javascript backbone.js routes requirejs amd

我得到了以下router.js:

define(['jquery', 'underscore', 'backbone', 'views/settings/index'], function($, _, Backbone, SettingsView) {

    var Router = Backbone.Router.extend({

        container: $('div.main'),

        routes: {
                "settings": "settings"
                , "settings/:query": "settings"
        },

        settings: function(query) {
            this.container.html(SettingsView.render().el);
        }

    });

    if (Router._instance) return Router._instance;

    Router._instance = new Router();

    return Router._instance;

});

在main.js字段中调用路由器,该字段在requirejs config中被标记为第一个依赖项:

define(['jquery', 'underscore', 'backbone', 'router'], function($, _, Backbone, router) {

    // ajax settings (sent cors cookies)
    $.ajaxSetup({ xhrFields: { withCredentials: true } });

    // register master router
    window.router = router;

    // start backbone history
    Backbone.history.start({ root: "/" });          

});

在某些观点中,我现在想做:

define(['jquery', 'underscore', 'backbone', 'router'], function($, _, Backbone, router) {

    var View = Backbone.View.extend({

        initialize: function() {
            router.on('route:settings', this.change, this);
        },

        change: function(query) {
            // load some new content for example
        }

    });

    return View;

});

我收到此错误消息:

Uncaught TypeError: Cannot call method 'on' of undefined 

更新 我为每个模块添加了一个console.log。所以我知道模块的执行顺序。我提到requirejs的顺序错误:

view.js -> main.js -> router.js

而不是:

router.js -> main.js -> view.js

让我们看看如何解决这个问题

UPDATE2: 我现在将路由器事件绑定部分包装到setTimeout循环中:

        setTimeout(function() {
            window.router.on('route:settings', this.select, this);        
        }.bind(this), 20);

看到它有效!

这真的只是一个修复,但仍然是一个修复:)

3 个答案:

答案 0 :(得分:1)

为什么要尝试在路由器上创建单例实例?

就我理解而言,Requirejs只解析每个模块一次 就我所期望的任何体面的模块加载器而言。

#router.js
define(['jquery', 'underscore', 'backbone', 'views/settings/index'], 
  function($, _, Backbone, SettingsView) {
  //your code omitted ...

  //no need to do this
  //if (Router._instance) return Router._instance;
  //Router._instance = new Router();
  //return Router._instance;

  //this should work as well and give you a "singleton" instance
  return new Router();

});

答案 1 :(得分:1)

  1. 请检查您给requirejs.config()的名称/路径是否正确。因为我有一个轻微的错字,我已经很难打了几次墙。 requirejs不会在这种情况下返回任何错误,但遗憾的是只有未定义。
  2. 如果你确定没有拼写错误,我会尝试将main.js作为对视图定义的明确依赖。

答案 2 :(得分:0)

我认为您需要在第一个Router的末尾返回对define对象的引用。

define(['jquery', 'underscore', 'backbone', 'views/settings/index'], function($, _, Backbone, SettingsView) {

    var Router = Backbone.Router.extend({

        container: $('div.main'),

        routes: {
            "settings": "settings"
            , "settings/:query": "settings"
        },

        settings: function(query) {
            this.container.html(SettingsView.render().el);
        }

    });

    var Singletonizer = function(Singleton) {
        if (Singleton._instance) return Singleton._instance;

        Singleton._instance = new Singleton();

        Singletonizer(Singleton);
    };

    return Singletonizer(Router);
});