2013-04-30 108 views
0

在這個簡單的要求/骨幹網應用Require.js模塊沒有看到骨幹Router.js

https://github.com/thisishardcoded/require-prob

爲什麼app.js看到路由器,但TestView.js不是?

這裏是app.js

define(['router'],function (Router) { 

第一線,這裏是TestView.js

define(['backbone','router'],function(Backbone,Router){ 

檢查出完整的詳細信息,下載回購的第一線,運行和檢查控制檯日誌如果你覺得如此傾向

謝謝! Jim

更多:好的,答案是 - 因爲它的加載順序,即使改變了,我有一個循環依賴不是嗎? TestView需要路由器,路由器需要TestView。

在這種情況下,解決方案可能是

var r=require('router); 
r.navigate or whatever 

但是,這似乎是一個恥辱,路由器是不能直接訪問無處不在,是上述方法中好的做法呢?

回答

5

當然這是因爲循環依賴的。要解決它,你要麼傳遞路由器來查看構造函數,並從視圖的模塊中刪除路由器依賴項,或者在你的視圖中使用require('router')。

第一種選擇,router.js:

app_router.on('route:test', function() { 
    var testView = new TestView({router: app_router}); 
    testView.render(); 
}) 

第一種選擇,view.js:

define(['backbone'], function(Backbone){ 

    var TestView=Backbone.View.extend({ 
     el: '#test', 
     initialize: function() { 
      // get router from constructior options 
      this.router = this.options.router 
     }, 
     render: function(){ 
      this.$el.html('<p>Foo!</p>'); 
      console.log("TestView.js does not find 'Router',", this.router); 
     } 
    }); 

    return TestView; 

}); 

第二個選項,view.js:

define(['backbone','router'], function(Backbone, router){ 

    // at this point router module is not loaded yet so router is undefined 

    var TestView=Backbone.View.extend({ 
     el: '#test', 
     initialize: function() { 
      // at this point router module is loaded and you may access it with require call 
      this.router = require('router'); 
     }, 
     render: function(){ 
      this.$el.html('<p>Foo!</p>'); 
      console.log("TestView.js does not find 'Router',", this.router); 
     } 
    }); 

    return TestView; 

}); 

第二個選項也這裏描述:http://requirejs.org/docs/api.html#circular

+0

謝謝,是的,我從那以後意識到我有一個循環依賴 - 我想我正在考慮路由器在整個應用程序可用的單身人士,所以......這是考慮好的做法是繞過路由器,也可以使用require()內聯來說話嗎? – Jim 2013-05-01 09:52:25

+1

我試圖解決你在路由器中查看路由的問題。但是現在,既然您已經問過這個問題的好壞,我想我不會選擇這種方式,因爲它會導致組件緊密結合。相反,我會讓路由器監聽視圖的事件並調用視圖的方法。所以如果視圖需要路由器做某件事情,它會觸發事件。如果路由器需要使用視圖,它將調用它的公共方法。 – 2013-05-01 12:13:30

0

我下載並檢查了您的代碼。以下可能是問題:

  1. require.js只適用於AMDs。由於主幹不再支持AMD。您將需要使用啓用BackboneAMD版本。你可以得到它here

  2. TestView是你的路由器的依賴。所以它在路由器加載之前加載。

您可能想要改進編碼模式。這裏是我的建議:

App.js

define([ 

'骨幹', '路由器', ]功能(骨幹,MainRouter){ '使用嚴格的';

var AppView = Backbone.View.extend({ 

    initialize: function(){ 

     App.router = new MainRouter(); 
     Backbone.history.start(); 
    } 
}); 

return AppView; 
}); 

Router.js

define([ 
    'backbone', 
    'view/TestView' 
], function(Backbone, TestView){ 
    var Main = Backbone.Router.extend({ 
     routes: { 
      'test': 'test' 
     }, 

     test: function(){ 
      new TestView({ 
       // pass model or collection to the view 
       // model: new TestModel // remember to require 
      }); 
     } 

    }); 

    return Main; 
}); 

編輯 監聽事件:

// in main.js 
var window.Vent = {}; 

_.extend(window.Vent, Backbone.Events); 

// now in any view you can trigger a event 
$('something').on('click', function(){ 
    window.Vent.trigger('somethinghappened', this); 
    // this is reference to current object 
}); 

// now in other view you can do 
window.Vent.on('somethinghappened', this.run, this); 
// this in the end is the reference we passed when event was triggered 

run: function(obj){ 
    //this function will run when the event is triggered 
    // obj is the object who triggered the event 
} 

PS:你爲什麼要在視圖中使用的路由器?我已經構建了很多骨幹應用程序。從來沒有需要這樣做。

+0

嗨,1)沒有意識到主幹不再是AMD謝謝2)是的,自從發佈我意識到有一個循環依賴3)我想我想'路由器'就像整個應用程序可用的單身人士,原因我想在視圖中使用它是因爲對話框上的關閉按鈕應該啓動另一個視圖4)但是..我已經意識到我有點誤解了路由器的使用 - 我正在使用一個事件調度員現在改爲 – Jim 2013-05-01 09:50:16

+0

偉大,你正在做你的研究。我已經添加了您可能想要遵循的示例模式。我一直在使用它。好像你可能想要使用事件。您可以觸發事件並在另一個視圖中偵聽它。我將爲此添加一些示例代碼。 – Subash 2013-05-01 09:55:06

+0

謝謝!我是一個閃光/動作難民:)迄今我loooooooving JavaScript - 上次我碰它是十年前,OMG!它長大了 - 對不起話題 – Jim 2013-05-01 11:04:31

0

您可以使用可用的Backbone.history.navigate來實現您的目標更容易,因爲Router.navigate是一個簡單的包裝。考慮這個part of Backbone source

navigate: function(fragment, options) { 
    Backbone.history.navigate(fragment, options); 
    return this; 
},