2012-08-31 28 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