2012-08-31 27 views
1

我得到了以下router.js:RequireJs:错误的模块顺序

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 

UPDATE: 我加入的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); 

并看到它的作品!

这真正公正是一个修复,但仍然修复:)

+1

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

回答

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

});

+0

您需要迄今为止的singelton,以便始终获得同一个对象实例。神奇的是新的关键字^^ – bodokaiser

+0

也许我不够清楚。 每个加载的模块只执行一次,结果(返回的对象)将被缓存和重用。 – robkuz

0

我认为你需要在第一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); 
}); 
+0

我现在直接在路由器被调用的文件中添加了一个事件监听器。有事件听取成功。在视图本身,我得到错误。因此,出于某种原因,路由器不能作为模块使用。...... – bodokaiser

1
  1. 请检查您给予requirejs.config()的名称/路径是否正确。因为我有一个轻微的错字,我几次打墙。 requirejs不会在这种情况下返回任何错误,但可悲的是只有未定义。
  2. 如果您确定没有错别字,我会尝试将main.js作为显式依赖于您的视图的定义。
+0

一:它不能是一个错字。 router.js文件直接位于根目录中,因此没有路径快捷方式。二:这是一个非常好的主意!我试过了,不幸的是它没有工作。不过,我慢慢地认为我们有一个错误 – bodokaiser