2013-07-15 29 views
0

有没有办法通常拦截MarionetteJS操作,如路由和模型抓取?有没有办法拦截木偶路线和模型提取?

并行将是$ httpInterceptor在AngularJS(https://stackoverflow.com/a/11957760/41887

使用情况我感兴趣的处理是用户认证,重定向到一个登录页面/路径应该有没有当前用户的身份验证。虽然我可以在每个控制器中专门处理这个问题,但我希望有一个全局应用的通用机制。

更新:

有关读取拦截我见过一个建议如下:

AuthenticationModule.addInitializer -> 
    # Tell jQuery to watch for any 401 or 403 errors and handle them appropriately 
    $.ajaxSetup { 
    statusCode: { 
     401: -> window.location.replace('#login') 
     403: -> window.location.replace('#denied') 
    } 
    } 

,但如果你想验证反对的东西除了它不工作,以及HTTP响应代码(即用户实体/内存中的表示)。

+0

事实上,我最终通过在jquery的ajax调用中设置默认行为来使用类似于您的解决方案,我对此感到非常满意。你能举一个你想要获得什么的例子吗? – Ingro

回答

1

Marionette.AppRouter扩展了标准Backbone.Router,它们都没有提供拦截机制,允许您阻止执行路由回调。需要相同的功能,我想出了以下代码(_Lodash)。在原始Backbone.Router.prototype.route()中,将创建将在路线匹配上执行的功能。以下代码为原始Backbone.Router.prototype.route()提供了一个包装器,以便用执行一系列中间件功能的函数替换已注册的路由回调。这些中间件中的每一个都可以在执行原始路由回调之前或之后执行任何附加处理,包括阻止执行进一步回调并引发异常。

Backbone.RouteMiddlewares.use(function (route, name, fragment, args, next) { 
    if (App.routeRequiresAuthentication(name) && !App.isUserAuthenticated()) { 
    Backbone.history.navigate('login', {trigger: true}); 
    } 
    else { 
    next(); 
    } 
}); 

注:

Backbone.RouteMiddlewares = (function() { 

    var Backbone = require('backbone') 
    , _ = require('lodash'); 

    /** 
    * A wrapper for `Backbone.Router.prototype.route()` that will use route middlewares (in addition to its 
    * normal callback). 
    * 
    * @param {Function} fn - The wrapped function (should be compatible with `Backbone.Router.prototype.route()`). 
    * @param {string|RegExp} route - A route pattern or regexp. 
    * @param {string} name - The name of the route. 
    * @param {Function} callback - The route callback. 
    * @returns {Backbone.Router} 
    */ 
    function RouteMiddleware(fn, route, name, callback) { 
    // Prepare arguments as the original Backbone.Router.prototype.route() would. 
    if (!_.isRegExp(route)) route = Backbone.Router.prototype._routeToRegExp.apply(this, [route]); 
    if (_.isFunction(name)) { 
     callback = name; 
     name = ''; 
    } 
    if (!callback) callback = this[name]; 

    // Execute the wrapper `route` method, with the callback as final middleware. 
    return fn.apply(this, [route, name, function() { 
     executeMiddlewares.apply(this, [route, name, Backbone.history.getFragment(), Array.prototype.slice.apply(arguments, [0]), callback]); 
    }]); 

    }; 

    /** 
    * Add a route middelware. 
    * 
    * @param {RouteMiddleware} fn 
    */ 
    RouteMiddleware.use = function use(fn) { 
    middlewares.push.apply(middlewares, _.filter(arguments, _.isFunction)); 
    }; 

    /** 
    * @callback RouteMiddleware 
    * @param {RegExp} route - The matched route regexp. 
    * @param {string} name - The matched route. 
    * @param {string} fragment - The matched URL fragment. 
    * @param {Array} args - The route arguments (extracted from `fragment`). 
    * @param {Function} next - The function to call to execute the next middleware in the chain. 
    */ 

    /** 
    * @type {RouteMiddleware[]} 
    */ 
    var middlewares = []; 

    /** 
    * Execute the route middlware, ending with the provided callback. 
    * 
    * @param {RegExp} route - The matched route regexp. 
    * @param {string} name - The matched route. 
    * @param {string} fragment - The matched URL fragment. 
    * @param {Array} args - The route arguments (extracted from `fragment`). 
    * @param {Function} callback - The route handler to execute as final middleware. 
    */ 
    function executeMiddlewares(route, name, fragment, args, callback) { 
    var index = 0; 
    var h = middlewares.concat(function (route, name, fragment, args, next) { 
     callback.apply(this, args); 
    }); 
    function next(err) { 
     if (err) throw err; 
     h[index++].apply(this, [route, name, fragment, args, next.bind(this)]); 
    } 
    next.apply(this); 
    } 

})(); 

Backbone.Router.prototype.route = _.wrap(Backbone.Router.prototype.route, Backbone.RouteMiddlewares); 

使用该拦截器/中间件机制,用户在登录页面的重定向可以用下面的实现如果能够通过中间件路线回调后执行代码与路由器上的route事件以及Backbone.history都是多余的,但它随中间件模式一起提供。

0

您可以使用Backbone.sync。该同步是Backbone在每次获取,保存操作时调用的功能。默认情况下,它使用jquery ajax进行调用。您可以重写Backbone.sync函数中的ajax调用,以便您可以控制服务器交互。这里是Backbone.Sync documentation

相关问题