Angular Router.navigate使用relativeTo跳转未生成正确子路由URL
问题场景
给定Angular路由配置如下:
{ path: '', component: IndexComponent, children: [ {path: 'table', component: TimetablesStaticComponent}, { path: 'comparison/:id', component: TimetablesAllComponent, children: [ { path: 'table', component: TimetablesStaticComponent, }, ], }, ], }
实际运行现象:
- 从默认根路径跳转
table路由正常,访问localhost:4200/table可成功加载TimetablesStaticComponent - 需求为在服务中触发跳转至table组件时保留前序路由:当前处于
localhost:4200/comparison/123路由下时,预期跳转到localhost:4200/comparison/123/table - 实际调用代码
this.router.navigate(['table'], {relativeTo: this.activatedRoute});后,跳转到了localhost:4200/table,不符合预期
问题原因
服务中直接注入的ActivatedRoute实例没有绑定当前页面的激活子路由上下文:
- 当服务在根注入器(或非路由组件层级注入器)提供时,注入得到的
ActivatedRoute默认指向路由树的根节点,而非当前comparison/:id路由对应的子路由节点 - 相对导航
relativeTo参数传入根路由节点时,跳转基准路径就是根路径,因此会匹配到根节点下的table子路由,而非comparison/:id节点下的table子路由
修正方案
- 方案1:从调用方传入正确的路由上下文
不要在服务内直接注入使用ActivatedRoute,改为在触发跳转的页面组件中(该组件本身处于comparison/:id路由下,注入的ActivatedRoute是当前路由节点实例),将当前路由实例作为参数传入服务的跳转方法:// 组件中调用服务方法 constructor(private route: ActivatedRoute, private navService: NavigationService) {} jumpToTable() { this.navService.navToTable(this.route); } // 服务中实现跳转 navToTable(currentRoute: ActivatedRoute) { this.router.navigate(['table'], {relativeTo: currentRoute}); } - 方案2:服务内部主动获取当前最深层激活路由
如果需要服务内部自行获取路由上下文,可通过RouterState遍历路由树,拿到当前最末端的激活路由作为相对导航基准:private getCurrentActiveRoute(): ActivatedRoute { let route = this.router.routerState.root; while (route.firstChild) { route = route.firstChild; } return route; } // 跳转时使用 navToTable() { this.router.navigate(['table'], {relativeTo: this.getCurrentActiveRoute()}); }
补充:
comparison/:id路由对应的TimetablesAllComponent模板中需要配置<router-outlet></router-outlet>,否则子路由table无法正常渲染。
内容的提问来源于stack exchange,提问作者Glupiy
相关产品推荐
相关产品推荐

