Маршруты Backbone.js не стреляют - PullRequest
1 голос
/ 22 марта 2012

У меня есть базовый маршрутизатор, где я определяю некоторые функции, которые нужно запускать везде. Каждый маршрутизатор расширяет этот маршрутизатор.

Теперь моя проблема в том, что ни один из моих маршрутов, определенных в этом базовом маршрутизаторе, фактически не запускается. Все остальные маршруты в других роутерах работают нормально. Я создал тестовый маршрут под названием «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

Поэтому, когда я захожу на «/ регистрация» или «/ а», он должен запускать соответствующий метод, но это не так. Интересно, это как-то связано с тем, что другие маршрутизаторы расширяются от этого маршрутизатора? Будет проводным, но это единственное, о чем я могу думать, потому что любой другой маршрутизатор работает нормально.

Обновление

Я думаю, что я нашел обходной путь, создав экземпляр Базового маршрутизатора в моем файле .js основного приложения. Вот что я делаю сейчас:

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

Видите ли вы какие-либо возможные проблемы с этим?

Ответы [ 2 ]

3 голосов
/ 22 марта 2012

Проблема в том, что 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'.Вот демонстрация с простыми (не Backbone) классами 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, поскольку последовательность построения немного отличается:

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

Так@routes необходимо правильно настроить до вызова initialize;это означает, что вы не можете объединить новые маршруты в @routes в вашем initialize и ожидать, что они будут подключены.Кроме того, вы, вероятно, не хотите указывать constructor при использовании Backbone, поскольку вам необходимо полностью реализовать стандартный конструктор Backbone.Router и добавить в него дополнительные элементы.

Парапараметры сразу появляются:

  1. Вручную добавить маршруты подкласса, вызвав route в подклассах initialize.
  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 голосов
/ 22 марта 2012

Мой 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 эквивалентен?Если нет, то это может быть вашей проблемой.

...