Backbone.js路由没有触发

时间:2012-03-21 22:22:05

标签: backbone.js coffeescript

我有一个基本路由器,我定义了一些需要在任何地方运行的功能。每台路由器都扩展了这台路由器。

现在我的问题是,我在这个Base路由器中定义的所有路由都没有。其他路由器中的每个其他路由都可以正常工作我创建了一个名为'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

因此,当我访问'/ register'或'/ a'时,它应该触发相应的方法,但事实并非如此。我想知道它是否与其他路由器从这个路由器扩展的事实有关?将是有线的,但这是我唯一能想到的,因为每个其他路由器工作正常。

更新

我想我已经通过在我的主应用程序.js文件中实例化基本路由器找到了解决方法。这就是我现在所做的:

new Etaxi.Routers.Base() (this is the new one)
new Etaxi.Routers.Videos()

你认为这有什么问题吗?

2 个答案:

答案 0 :(得分:3)

问题是extends不会合并类中的属性,子类的属性将完全替换超类。例如,鉴于这些:

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

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

然后routes实例的R将只是'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.Router,因为construction sequence有点不同:

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

因此,在调用 @routes之前,需要正确设置{em} <{1}};这意味着您无法将新路由合并到initialize @routes中,并希望它们能够连接起来。此外,您可能不希望在使用Backbone时提供initialize,因为您必须完全实现标准的Backbone.Router构造函数,并在其中间放置额外的东西。

一些选项立即出现:

  1. 通过调用子类constructor中的route手动添加子类的路由。
  2. 将路由保留在基类之外,向基类添加一个方法,使用initialize调用添加基类的路由,然后在子类route方法中调用该方法。
  3. 另一种可能的选择是做这样的事情:

    initialize

    这应该会在正确的时间在子类的class R extends Backbone.Router routes: 'a': 'b' class RR extends R @::routes = _({}).extend(R::routes, 'c': 'd') 中获得{ 'a': 'b', 'c': 'd' };我还没有完全测试过这个,但它确实可以在一个简单的演示中运行:http://jsfiddle.net/ambiguous/QQbrx/

    尽管如此,所有的混乱可能毫无意义。您可以拥有任意数量的路由器,因此可能完全没有子类化。例如,这很好用:

    routes

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

答案 1 :(得分: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是否相同?如果没有,那可能是你的问题。