我有一个 Durandal 应用程序,router.mapUnknownRoutes
如果 URL 不对应于已知路由,我会使用它来显示用户友好的错误页面。这很好用——如果我去,说/foo
,并且与路线不匹配,那么指定的模块mapUnknownRoutes
会正确显示。
但是,当我有参数化路由并且参数与后端的任何内容都不匹配时,我找不到任何方法来显示相同的错误页面。
例如,假设我有一条路线people/:slug
,对应模块的activate
方法如下所示:
this.activate = function (slug) {
dataService.load(slug).then(function () {
// ... set observables used by view ...
});
};
如果我去,说/people/foo
,那么结果取决于是dataService.load('foo')
返回数据还是错误:
- 如果
foo
后端存在,那么没问题 - 设置了可观察对象并继续组合。 - 如果
foo
不存在,则抛出错误(因为没有catch
)。这会导致未处理的错误,从而导致导航被取消并且路由器停止工作。
我知道我可以返回false
,canActivate
并且导航将以更干净的方式取消,而不会破坏路由器。然而,这不是我想要的;我想要一个无效的 URL 来告诉用户出了点问题。
我知道我可以{ redirect: 'not-found' }
从canActivate
. 然而,这很糟糕,因为它破坏了后退按钮——在重定向发生后,如果用户按下后退,他们会返回到/people/foo
这会导致另一个错误,因此会再次重定向到not-found
.
我尝试了几种不同的方法,主要涉及添加catch
对 promise 定义的调用:
this.activate = function (slug) {
dataService.load(slug).then(function () {
// ... set observables used by view ...
}).catch(function (err) {
// ... do something to indicate the error ...
});
};
activate
(或)是否可以canActivate
通知路由器该路由实际上是无效的,就好像它从一开始就从未匹配过一样?activate
(or )是否可以canActivate
发出 arewrite
(而不是 aredirect
) 以便路由器在不更改 URL 的情况下显示不同的模块?- 我可以直接
compose
用其他模块代替当前模块(并取消当前模块的组成)吗?
我还尝试了一个空catch
块,它吞噬了错误(我可以在这里添加一个 toast 来通知用户,这总比没有好)。然而,这会导致很多绑定错误,因为视图所期望的 observables 从未设置过。可能我可以将整个视图包装在if
绑定中以防止错误,但这会导致空白页面而不是错误消息;或者我必须将错误消息放入每个可能无法检索其数据的视图中。无论哪种方式,这都是视图污染而不是 DRY,因为我应该只写一次“未找到”错误消息。
我只想要一个无效的 URL(特别是与路由匹配但包含无效参数值的 URL)来显示一个显示“找不到页面”的页面。当然,这也是其他人想要的吗?有什么办法可以做到这一点?