Я сталкивался с этой проблемой ранее и думал, что поделюсь своим решением для вставки «промежуточного программного обеспечения» в поток маршрутизации Backbone. Цель состояла в том, чтобы перенаправить пользователей в различные потоки в зависимости от некоторых условий, например, флагов функций, обработки сеансов и т. Д.
Backbone.ProtectedRouter = Backbone.Router.extend({
/*
* Subclass of Router that monkeypatches route in order to protect certain
* routes.
*
* If you want to add a protected route, add it to the protectedRoutes
* object in this form:
* route: { method: fn, assertion: fn, args: [args..] }
*
* * method => the method to call if the assertion is true (the route should
* be protected in the given scenario)
*
* * assertion => the function that decides whether or not the route
* should be rendered
*
* * args => the arguments to be passed to method
*/
route: function(route, name, handler) {
var _this = this;
Backbone.Router.prototype.route(route, name, function(){
var boundHandler = _.bind(handler, _this),
attrs, method, args, dfd;
attrs = _.has(_this.protectedRoutes, route) ? _this.protectedRoutes[route] : null;
if ( attrs && !attrs.assertion() ) {
// In this scenario my flows all return Deferreds
// you can make this event based as well.
dfd = _this[attrs.method].apply(_this, attrs.args.concat([route]));
dfd.then(boundHandler);
} else
boundHandler.apply(_this, arguments);
});
}
});
Оттуда вы можете просто расширить Backbone.ProtectedRouter
с помощью хеша protectedRoutes
следующим образом:
var router = Backbone.ProtectedRouter.extend({
protectedRoutes: {
'home': {
assertion: function() { return is_logged_in; },
method: 'renderLogin',
args: ['some_arg']
}
},
routes: {
'home': 'renderHome'
},
...
});
В этом случае, если запрос сделан для маршрута home
и is_logged_in
равен false
, метод renderLogin
вызывается и передается 'some_arg'
. После потока renderLogin
вернет разрешенное значение Deferred, которое вызывает исходный обработчик (renderHome
).
Надеюсь, это поможет. Я очень открыт для предложений! :)