【问题标题】:How to handle 'no route matched' in Ember.js and show 404 page?如何处理 Ember.js 中的“没有匹配的路由”并显示 404 页面?
【发布时间】:2013-01-10 23:57:17
【问题描述】:

我该如何处理错误

Uncaught Error: No route matched the URL '...'

并显示自定义 404 页面?


注意:这个问题在几个月前和 answered 之前被问过 - 但现在不再有用了。

【问题讨论】:

    标签: ember.js


    【解决方案1】:
    App.Router.map(function() {
      //set up all of your known routes, and then...
      this.route("fourOhFour", { path: "*path"});
    });
    

    .. 您定义了 FourOhFourRoute 以显示您选择的“找不到路由”消息。您将能够访问fourOhFour路由中最初请求的路径作为路径参数。

    编辑:为了清楚起见——这个答案是在其他人被报告不再工作之后发布的。

    编辑 2:我已更新答案以反映 Yehuda Katz 的评论(如果我错了,请 LMK)。

    【讨论】:

    • 谢谢!当我第一次尝试这个时,我确实错过了冒号。这应该记录在某处!
    • : 应该不是必需的,但参数名称是(因此,如果您愿意,可以从您的路线中获取)。 *path 是我使用的。
    • 如果您使用的是 ember cli,您的模板文件应该被 dasherized(即四个-oh-four.hbs)
    【解决方案2】:

    这是一个例子:

    我使用通配符路由定义路由器中的最后一条路由,请参阅:http://emberjs.com/guides/routing/defining-your-routes/#toc_wildcard-globbing-routes

    我有一个/not-found 路由,请参阅我的路由器/*path 中定义的最后一个路由以捕获任何文本字符串,请参阅:https://github.com/pixelhandler/blog/blob/master/client/app/router.js#L19

    Router.map(function () {
      this.route('about');
      this.resource('posts', function () {
        this.resource('post', { path: ':post_slug' });
      });
      this.resource('admin', function () {
        this.route('create');
        this.route('edit', { path: ':edit_id' });
      });
      this.route('not-found', { path: '/*path' });
    });
    

    该路由重定向到/not-found,请参阅:https://github.com/pixelhandler/blog/blob/master/client/app/routes/not-found.js

    import Ember from 'ember';
    export default Ember.Route.extend({
      redirect: function () {
        var url = this.router.location.formatURL('/not-found');
        if (window.location.pathname !== url) {
          this.transitionTo('/not-found');
        }
      }
    });
    

    此外,任何带有钩子(例如modelbeforeModelafterModel)的路由都会导致 promise 被拒绝,可以使用 error 操作转换到 404。

    actions: {
      error: function (error) {
        Ember.Logger.error(error);
        this.transitionTo('/not-found');
      }
    }
    

    呈现not-found 模板,请参阅:https://github.com/pixelhandler/blog/blob/master/client/app/templates/not-found.hbs

    <h1>404 Not Found</h1>
    <p>
      Perhaps you have a link that has changed, see {{#link-to 'posts'}}Archives{{/link-to}}.
    </p>
    

    这是我的 404 页面:http://pixelhandler.com/not-found

    【讨论】:

    • 我最终在这里写了一篇关于这个主题的帖子:pixelhandler.com/posts/…
    • 很好的解决方案!我发现使用 replaceWith 而不是 transitionTo 更合适,否则如果用户点击浏览器上的“返回”按钮,他们将始终被重定向回 /not-found 页面,因为他们试图返回之前的页面最初没有找到。
    【解决方案3】:

    您可以尝试在路由器末尾添加一条包罗万象的路由:

    App.Router.map(function() {
      this.resource('post', ...);
      this.resource('user', ...);
      this.route('catchAll', { path: '/*' });
    });
    
    App.CatchAllRoute = ...
    

    【讨论】:

    • 我实际上从来没有这样想过 - 但我需要为每个资源提供一个“catchAll”......目前可以作为一种解决方法,但我想知道是否有更好的方法......跨度>
    【解决方案4】:

    在 Ember 2.x 中

    App.Router.map函数内部,将代码放在回调函数的末尾。

    this.route('your_handler_route_name', { path: '/*path' });
    

    现在每条被先前定义的路线捕获的路线都将被your_handler_route_name路线捕获。

    【讨论】:

    • 这是一个很好的答案。但我遇到的问题是,如果我有更复杂的 URL(即 mysite/good_directory/bad_directory),那么我就会遇到困难。
    【解决方案5】:

    解决方案 1

    显示404内容:

    App.Router.reopen({
            handleURL: function (url) {
                try {
                    return this._super(url);
                } catch (error) {
                    if (error.message.match(/No route matched the URL/)) {
                        return this._super('/404');
                    }
                }
            }
        });
    

    如果您也想将 URL 更改为 404:

    App.Router.reopen({
            location: locationImplementation,
            handleURL: function (url) {
                try {
                    return this._super(url);
                } catch (error) {
                    if (error.message.match(/No route matched the URL/)) {
                        this.transitionTo('404');
                        return this._super('/404');
                    }
                }
            }
        });
    

    要了解这里发生的事情,请参阅 ember rc2 中的 22636 行。

    解决方案 2

    使用App.Router.router.recognizer.hasRoute('route.path.goes.here');解析当前URL并检查路由或资源是否存在

    【讨论】:

    • 这看起来是个好方法!但是错误消息上的匹配似乎很脆弱..
    • @stephanos 这是迄今为止我发现的最好的。无论如何,在这个 ember 版本消息不会改变,所以当升级到 rc3 时我会检查它。另一种选择是覆盖 Ember.js 的这一部分 - 在 JS 中非常简单,最后一个函数获胜。
    • 这似乎不起作用,请在行:“this._super(url);”处提供替代方案,没有抛出异常。也许它被承诺模式延迟了。 (ember v1.9.1)
    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 2015-11-17
    相关资源
    最近更新 更多