假设我们有以下路由配置:
[{ path: "people", children: [ { path: ":id", component: PersonProfileComponent, resolve: { person: PersonResolver }, children: [ { path: "", component: PersonOverviewComponent }, { path: "photos", component: PersonPhotoListComponent } ] } ] }, { path: "404", component: PageNotFoundComponent }, { path: "**", component: PageNotFoundComponent }]
当用户尝试导航到以下任何一个时,我想重定向到404页面:
/people/{non-existing-id} /people/{non-existing-id}/photos /people/{existing-id}/{non-existing-subpage}
第三种情况由**路由处理,因为它与之前的任何路由都不匹配.所以PersonResolver
必须处理前两种情况.
export class PersonResolver implements Resolve{ constructor(private peopleService: PeopleService, private router: Router) { } resolve(route: ActivatedRouteSnapshot): Observable { return this.peopleService.find(id).catch(error => { if (error instanceof Response) { if (error.status === 404) { this.router.navigate(["/404"]); } else { //todo } } else { //todo } return Observable.of(null); }); } }
一切正常但问题是当显示404页面时,浏览器URL更新为
(如预期的那样).我的问题是如何将URL设置为我们刚刚取消的路径(例如
),因为这就是在整个网络上处理404的方式.(我也试过去{skipLocationChange: true}
,router.navigate()
但是在我们尝试导航之前保留了位置)
它可能改变URL,而无需使用导航Location
- 文档
您可以对错误做出反应,订阅Router.events - NavigationError
,然后显示404,skipLocationChange
然后通过更改位置location.go
导航到404后,您必须更改url。
constructor(router: Router, location: Location) { router.events .filter(event => event instanceof NavigationError) .subscribe((event: NavigationError) => { router.navigate(["/404"], {skipLocationChange: true}) .then(() => location.go(event.url)); }) }
我希望在路由模块中执行此操作,但是也可以在解析器中执行此操作。
Router.events
尚未很好地记录在案,您可以至少在此处检查它们的列表并进行一些日志记录。