Ember Router - 如何处理404(未找到)路由?

Wes*_*man 14 ember.js ember-old-router

我正在试图弄清楚如何使用我的应用程序处理无效路由Ember.Router.

目前,如果我输入无效路线,例如myapp.com/#FooBarDoesntExist,它将重定向到索引路线('/').我想要它,如果我可以定义一个notFound或404状态,它将路由到所以我可以通知用户发生了什么.而不是他们被倾倒在主页上.

mbr*_*ton 19

处理此问题的一个好方法是声明路由除了路由之外还映射所有可能的URL.你可以在这里举个例子:http://jsfiddle.net/mbreton/r3C9c/

var App = Ember.Application.create();

App.Router.map(function(){
    this.route('detail', {path: "detail"});
    this.route('missing', { path: "/*path" });
});


App.MissingRoute = Em.Route.extend({
    redirect: function () {
        Em.debug('404 :: redirection to index');
        this.transitionTo("index");
    }
});

App.ApplicationView = Em.View.extend({
    didInsertElement:function(){
        $('#missingLink').on('click', function (e){
            window.location.hash = "#/pepepepepep";
            return false;      
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

在此示例中,所有未知的URL都重定向到索引路由.


tok*_*rev 6

Ember.Router在其当前版本中不提供处理未知路由的方法.是时候破解了!

解决方案1 ​​ - 快速而肮脏

这里的想法如下.我们有Ember.Router.route(path)方法,它使用请求的(可能未知的)路径调用.调用此方法后,保证路由器的路径已知.因此,如果我们比较请求的路径和实际路径并且它们不同 - 那么请求的路径无效,我们可能会将用户重定向到404页面.

  App.Router = Ember.Router.extend({

    route: function(path) {
      this._super(path);
      var actualPath = this.get("currentState").absoluteRoute(this);
      if (path !== actualPath) {
        this.transitionTo("404page");
      }
    }
  });
Run Code Online (Sandbox Code Playgroud)

这种解决方案非常昂贵.例如,如果当前状态为"/ a/b/c",并且用户想要导航到"/ b/d/e/unknown",则路由器将尽职地输入已知状态"b","d"和"e",只有这样我们才会把路径丢弃为未知路径.如果我们可以在实际路由开始之前告诉它,那将是很好的.

解决方案2 - 摆弄私有方法

在这里,我们检查给定路径的有效性,然后告诉路由器继续:

App.Router = Ember.Router.extend({

checkPath: function (path) {
  path = path.replace(this.get('rootURL'), '').replace(/^(?=[^\/])/, "/"); 
  var resolvedStates = this.get("states.root").resolvePath(this, path);
  var lastState = resolvedStates.get("lastObject");
  return lastState.match.remaining == "";
},

route: function(path) {
  if (this.checkPath(path)) {
    this._super(path);
  } else {
    this.transitionTo("404page");
  }
}
});
Run Code Online (Sandbox Code Playgroud)

该解决方案也有其缺点 - 它使用resolvePath标记为私有的方法.不过,我会使用这个解决方案,因为它比第一个解决方案更有效.