2013-10-24 73 views
2

谷歌有很多话题,但任何完整的工作示例。骨干:路线前

如何以我可以检查条件并根据需要取消导航来包装路由器导航?

P.S.我看到_.wrap的想法,覆盖了Backbone.Router.prototype.route等,但没有完整的例子。 另外我看到backbone-route-filter,但没有想法如何将它集成到我的应用程序中。

+0

那些配置的路由将触发一些js代码,然后您可以执行任何js验证并使用window.location.replace()将该站点重定向到另一个url。这适合你吗? –

+0

重定向有一个问题,如果你重定向到一个url,这反过来又会导致死锁。要小心它。 –

回答

2

为了让我延长Backbone.Router。我希望我的路由器能帮助你。 我添加了一个属性toEvaluate与路由的前提条件,我添加了评估路由器的功能,将评估他们之前浏览某些路线。

我的路线的一个例子是:

var MySubRouter = Backbone.ModuleRoute.extend({ 
     //hasPermissions is static 
     //if you want a function of an instance you can use a function instead 

     evaluateRoutesFn: SomeView.hasPermissions, 

     toEvaluate: { 
      routeA: { 
       modulePreconditions: [SomeView.CONDITION_A, ...] 
      } 
     }, 

     routeA: function(param1, param2) { 
      //the route to navigate with preconditions 
     }, 

的方法与权限返回true或false或错误。

var MyView = ModuleView.extend({}, { 
    CONDITION_A: "conditionA", 
    hasPermissions: function (condition, properties) { 
      switch (condition) { 
       case MyView.CONDITION_A: 
        return app.ConditionA; 
       default: 
        return true; 
      } 
    } 
}); 

而更重要的是ModuleRoute。在这里你有我的moduleRoute的基础。我增加了更多的东西。像错误控制一样。我将所有当前路线保存在我的应用程序的每个模块中......还有更多。你可以添加你需要的任何东西。这真的很有用。

Backbone.ModuleRoute = Backbone.Router.extend({ 
     evaluateRoutesFn: null, 
     toEvaluate: null, 

     constructor: function (prefix, options) { 
      this._finalRoutes = {}; 
      Backbone.SubRoute.prototype.constructor.call(this, prefix, options); 
     }, 

     onRoutes: function (route) { 
      var aps = Array.prototype.slice; 
      var args = aps.call(arguments); 
      args.shift(); 
      var routeName = this.routes[route]; 

      var evalResult = true; 
      try { 
       var toEval = this.toEvaluate && this.toEvaluate[routeName]; 
       if (toEval) { 
        evalResult = this.evalPreconditions(toEval.modulePreconditions, args); 
        //more future preconditions 
       } 
      } 
      catch (err) { 
       evalResult = false; 
      } 

      if (evalResult) 
       try { 
        this._finalRoutes[route].apply(this, args); 
       } 
       catch (err) { 
        window.history.back(); //go back, error control... 
       } 
      else 
       window.history.back(); //no permissions, go back 
     }, 

     evalPreconditions: function (preconds, args) { 
      if (!this.evaluateRoutesFn) { 
       throw "WARNING: Evaluate routes function must be overriden to evaluate them. " + 
        "Don't assign toEvaluate if you won't do it. The evaluation has been skipped."; 
      } 
      if (!preconds) 
       return true; 

      var evalResult = true; 
      for (var i = 0, len = preconds.length; i < len; i++) { 
       evalResult = this.evaluateRoutesFn(preconds[i], args); 
       if (!evalResult) { 
        throw "ERROR: The precondition is not truth."; 
        break; 
       } 
      } 
      return evalResult; 
     }, 

     route: function (route, name, callback) { 
      this._finalRoutes[route] = (!callback) ? this[name] : callback; 
      var that = this; 
      callback = function (path) { 
       return function() { 
        var aps = Array.prototype.slice; 
        var args = aps.call(arguments); 
        args.unshift(path); 
        that.onRoutes.apply(that, args); 
       }; 
      } (route); 
      return Backbone.Router.prototype.route.call(this, route, name, callback); 
     } 
    }); 
1

您可以尝试重写Backbone.history.route:

var bbhRoute = Backbone.history.route; 
Backbone.history.route = function(route, callback) { 
    return bbhRoute.call(Backbone.history, route, function(fragment) { 
    // if (decide if you want to prevent navigation) { 
    // window.history.back(); // to ensure hash doesn't change 
    // return; 
    // } 

    // if you want to let it happen: 
    return callback.apply(this, arguments); 
    }); 
}; 
+0

不适合我。我从来没有输入函数 –

+0

你把这个代码放在哪里? –

+0

在路由器初始化方法 –