2012-03-21 104 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