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

Скажем, у меня есть базовый маршрутизатор, например:

routes:
  ""                          : "homepage"
  "catalog/:id"               : "catalogPage"
  "catalog/:id/products/:id2" : "productPage"

homepage   :           -> doStuff()
catalogPage: (id)      -> doOtherStuff()
productPage: (id, id2) -> doEvenMoreStuff()

и функция:

executeBefore = -> console.log("hello")

Если я хочу, чтобы executeBefore вызывался и выполнялся каждый раз при вызове маршрута и до соответствующего метода маршрута, есть ли простой способ сделать это отдельно от вставки вызова для executeBefore в начале каждого метода маршрута?

Ответ 1

Вы можете переопределить функцию route в классе маршрутизатора для перехвата вызовов маршрута:

var Router = Backbone.Router.extend({
    routes: {
        "" : "homepage",
        "catalog/:id" : "catalogPage"
    },

    route: function(route, name, callback) {
        var router = this;
        if (!callback) callback = this[name];

        var f = function() {
            console.log('route before', route);
            callback.apply(router, arguments);
            console.log('route after', route);
        };
        return Backbone.Router.prototype.route.call(this, route, name, f);
    },

    homepage: function() {
        console.log("homepage");
    },
    catalogPage: function(id) {
        console.log("catalogPage "+id);
    }
});

var r = new Router();
Backbone.history.start();

И демо http://jsfiddle.net/nikoshr/EdLzh/

Ответ 2

С 13 февраля 2014 года вы можете использовать router.execute(callback, args, name) (http://backbonejs.org/#Router-execute).

Итак, ваш перехватчик будет выглядеть примерно так.

routes: {
    '': 'homepage',
    'catalog/:id': 'catalogPage',
    'catalog/:id/products/:id2': 'productPage'
},
execute: function(callback, args, name) {
    // Do your stuff here
    executeBefore();

    if (callback) callback.apply(this, args);
}

https://github.com/jashkenas/backbone/commit/791033dc1aab53e9e5c9366f64a854224f851231

Ответ 3

вы также можете использовать backbone.routefilter плагин.

вы сможете установить фильтр для всех маршрутов

var Router = Backbone.Router.extend({
  routes: {
    "": "index",
    "page/:id": "page"
  },
  before: function( route, params ) { ... },
  after: function( route, params ) { ... },
  index: function(){ ... },
  page: function( route ){ ... }
});

Или выберите несколько маршрутов

var Router = Backbone.Router.extend({
  routes: {
    "": "index",
    "page/:id": "page"
  },
  before: {
    "": function( route ) { ... },
    "page/:id": function( route ) { ... }
  },
  after: function( route ) { ... },
  index: function(){ ... },
  page: function( route ){ ... }
});

Ответ 4

Вы можете играть с событиями:

Backbone.history.on('route', function () {
    // Do your stuff here.
    executeBefore();
});

Посещение # help/uploading приведет к срабатыванию маршрута: справки из маршрутизатора.

По-видимому, это было бы вызвано до перенаправления:

https://github.com/documentcloud/backbone/blob/master/backbone.js#L1243

Backbone.history.route(route, function(fragment) {
    var args = router._extractParameters(route, fragment);
    callback && callback.apply(router, args);
    router.trigger.apply(router, ['route:' + name].concat(args));
    router.trigger('route', name, args);
    Backbone.history.trigger('route', router, name, args);
});