2012-03-21 92 views
1

我有一個基本路由器,我定義了一些需要在任何地方運行的函數。每個路由器都擴展這個路由Backbone.js路由沒有觸發

現在我的問題是,在這個基礎路由器中定義的我的路由都沒有實際觸發。其他路由器中的其他路由工作正常。我創建了一個稱爲'a'的測試路線,它調用方法'b',它應該發出警報但沒有任何反應。

下面是代碼:(這是CoffeeScript中,不注重壓痕,它的罰款在我的文件)

class Etaxi.Routers.Base extends Backbone.Router 

routes: 
    'register' : 'registerDevice' 
    'a' : 'b' 

b: -> 
    alert "a" 

initialize: -> 
    @registerDevice() unless localStorage.device_id? 
    @getGeolocation() 

registerDevice: -> 
    @collection = new Etaxi.Collections.Devices() 
    @collection.fetch() 
    view = new Etaxi.Views.RegisterDevice(collection: @collection) 
    $('#wrapper').append(view.render().el) 

getGeolocation: -> 
    navigator.geolocation.getCurrentPosition (position) -> 
     lat = position.coords.latitude 
     lng = position.coords.longitude 
     #$('#apphead').tap -> 
     # alert 'Position: ' + lat + " ," + lng 

所以,當我參觀「/註冊」或「/ A」它應該發射適當的方法,但它沒有。我想知道它是否與其他路由器從此路由器延伸的事實有關?將有線,但它是我能想到的唯一的事情,因爲每個其他路由器工作正常。

更新

我想我已經在我的主要應用.js文件實例化基地路由器找到了解決辦法。這就是我現在所做的:

您是否看到任何可能的問題?

回答

3

問題是extends不會合並你的類中的屬性,子類的屬性將完全替代超類的屬性。例如,考慮到這些:

class Etaxi.Routers.Base extends Backbone.Router 
    routes: 
     'register' : 'registerDevice' 
     'a' : 'b' 

class R extends Etaxi.Routers.Base 
    routes: 
     'c': 'd' 

然後routesR實例將只是'c': 'd'。下面是用普通(非骨幹)演示CoffeeScript的類:http://jsfiddle.net/ambiguous/ScUs2/

如果您需要合併的屬性,你必須自己與像這樣做:

class M 
    m: { a: 'b' } 

class Pancakes extends M 
    constructor: -> 
     @m = _({}).extend(@m, a: 'B', c: 'd') 

演示:http://jsfiddle.net/ambiguous/SR6ej/

但是那種弄虛作假不會Backbone.Routerconstruction sequence工作是有一點不同:

var Router = Backbone.Router = function(options) { 
    options || (options = {}); 
    if (options.routes) this.routes = options.routes; 
    this._bindRoutes(); 
    this.initialize.apply(this, arguments); 
}; 

所以@routes需要正確設置之前initialize被調用;這意味着您無法將新路線合併到您的initialize中的@routes,並期望它們被吸引。另外,使用Backbone時,您可能不想提供constructor,因爲您必須完全實現標準的Backbone.Router構造函數,並在其中間放置額外的東西。

一對夫婦選擇立即出現了:

  1. 手動通過調用子類initializeroute添加子類的路線。
  2. 將路由離開基類,向基類添加一個方法,該方法使用route調用添加基類路由,然後在子類initialize方法中調用該方法。

另一個可能的選擇是做這樣的事情:

class R extends Backbone.Router 
    routes: 
     'a': 'b' 

class RR extends R 
    @::routes = _({}).extend(R::routes, 'c': 'd') 

這應該讓你{ 'a': 'b', 'c': 'd' }在子類中的routes在正確的時間;我還沒有完全測試過這個,但它在一個簡單的演示中工作:http://jsfiddle.net/ambiguous/QQbrx/

所有的混亂可能是毫無意義的。你可以擁有儘可能多的路由器,因此子類化可能完全沒有必要。例如,這工作得很好:

class R extends Backbone.Router 
    routes: 
     'a': 'b' 
    b: -> console.log('b') 

class RR extends Backbone.Router 
    routes: 
     'c': 'd' 
    d: -> console.log('d') 

new R 
new RR 
Backbone.history.start() 

演示:http://jsfiddle.net/ambiguous/mr83v/

+0

非常感謝您解釋詳細的問題。我已經用一個可能的解決方案更新了我的帖子,但我不確定這是否是一個好方法,也許你可以看看。 – 2012-03-21 23:35:07

+0

@ drale2k:我想我可能在評論時添加了類似的更新。有多條路線沒有錯,請檢查我更新的答案的底部。即使如此,'@ :: routes = _(R :: routes).extend('c':'d')'竅門簡直就是那種:) – 2012-03-21 23:40:09

+0

啊呵呵,所以我們有同樣的想法:)謝謝您! – 2012-03-21 23:45:52

0

我的CoffeeScript是生疏,但...這看起來關對我說:

class Etaxi.Routers.Base extends Backbone.Router 

通常在JS你會怎麼做:

Etaxi.Routers.Base = Backbone.Router.extend({ 
    ... // properties and methods of Etaxi.Routers.Base go here 
}); 

是您的CoffeeScript等同?如果不是,那可能是你的問題。

+0

CoffeeScript中的'類...... extends'是骨幹'extends' 「子類」 完全兼容。 – 2012-03-21 22:41:59

+0

啊。在這種情況下,就像調試檢查(您使用的routes屬性應該可以工作,但只是爲了讓我們可以獲得更多信息...),您是否可以嘗試在initialize中通過以下方法連接路由:this.route( 'register','registerDevice',this.registerDevice)? – machineghost 2012-03-21 22:48:30