【问题标题】:RequireJs: Wrong module orderRequireJs:错误的模块顺序
【发布时间】:2012-08-26 12:30:15
【问题描述】:

我得到了以下 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 配置中被标记为第一个依赖项:

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

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

更新 2: 我现在将路由器事件绑定部分包装到一个 setTimeout 循环中:

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

看看它的工作原理!

这确实只是一个修复,但仍然是一个修复:)

【问题讨论】:

  • 老实说,我认为您不应该以任何方式解决 setTimeout 的问题。

标签: javascript backbone.js routes requirejs amd


【解决方案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();

});

【讨论】:

  • 到目前为止,您需要一个单例,以便您始终获得相同的对象实例。神奇的是新关键字^^
  • 也许我不够清楚。每个加载的模块将只执行一次,结果(您返回的对象)将被缓存和重用。
【解决方案2】:
  1. 请检查您提供给 requirejs.config() 的名称/路径是否正确。我已经撞了几次墙,因为我有一个轻微的错字。 requirejs 在这种情况下不会返回任何错误,但遗憾的是只是未定义。
  2. 如果您确定没有错字,我会尝试将 main.js 包含为对视图定义的显式依赖。

【讨论】:

  • to one:不可能是错字。 router.js 文件直接位于根目录中,因此没有路径快捷方式。致二:这真是个好主意!我试过了,不幸的是它没有用。但是我慢慢地认为我们有一个错误
【解决方案3】:

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

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

【讨论】:

  • 我现在直接在调用路由器的文件中添加了一个事件监听器。有事件监听成功。在视图本身中,我得到了错误。所以由于某种原因,路由器不能作为模块使用 ....
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2017-08-22
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多