Angular 4嵌套路由参数存储及回退路由异常问题求助
我之前也遇到过类似的场景,用Angular的嵌套路由+相对导航就能完美解决这个问题。咱们一步步来梳理:
问题根源
你当前的ModifyMetaContentComponent是LayoutComponent的直接子路由,和Questionaire/:id是平级关系。这就导致跳转后URL脱离了Questionaire的嵌套结构,返回时硬编码的previousState指向/MetaContentList,但这个路由现在是Questionaire/:id的子路由,没有父级参数的话自然匹配不到,就会出现路由错误。
解决方案
1. 重构路由配置,把共享参数的页面嵌套在抽象路由下
首先调整路由结构,将ModifyMetaContentComponent移到Questionaire/:id的子路由中,这样URL会始终保留id参数,形成嵌套路径:/Questionaire/:id/ModifyMetaContent/:metaContentId/:title。修正后的路由配置如下(修复了原配置中缺失的逗号):
const routes: Routes = [ { path: '', component: LayoutComponent, children: [ { path: 'Home', component: HomeComponent, data:{icon:'fa-home'} }, { path: 'QuestionaireList', component: QuestionaireListComponent, data:{icon:'fa-list-ul', previousState:'/Home'} }, // 将ModifyMetaContent移到Questionaire/:id的子路由下 { path: 'Questionaire/:id', children: [ { path: 'MetaContentList', component: MetaContentListComponent, data:{icon:'fa-database', previousState:'/QuestionaireList'} }, { path: 'ModifyMetaContent/:metaContentId/:title', component: ModifyMetaContentComponent, data:{icon:'fa-database'} } ] }, { path: 'Questionaire/:questionnaireType', children: [ { path: 'AddQuestionnaire', component: CreateQuestionnaireComponent, data:{icon:'fa-plus', previousState:'/QuestionaireList'} }, ] }, { path: 'Questionaire/:questionnaireType/:id', children: [ { path: 'UpdateQuestionnaire', component: EditComponent, data:{icon:'fa-pencil', previousState:'/QuestionaireList'} }, { path: 'QuestionList', component: QuestionListComponent, data:{icon:'fa-pencil', previousState:'/QuestionaireList'} }, { path: 'ImportQuestion', component: ImportQuestionComponent, data:{icon:'fa-plus', previousState:'/QuestionaireList'} }, ] } ] } ];
2. 修改跳转逻辑,使用带参数的相对/绝对路由
在MetaContentList.Component.html中,需要获取当前路由的id参数,然后构建正确的跳转路径。可以通过注入ActivatedRoute来获取参数,然后用相对路由或绝对路由跳转:
方式1:相对路由(推荐)
在组件类中注入ActivatedRoute:
import { ActivatedRoute } from '@angular/router'; constructor(private route: ActivatedRoute) {}
然后在模板中使用相对路由跳转:
<a class="ui labeled positive icon small button" [routerLink]="['../ModifyMetaContent', '', questionnaireTitle]"> <i class="plus icon"></i> new metaContent </a>
这里的../表示跳转到当前路由的父级(也就是Questionaire/:id),然后进入ModifyMetaContent子路由,自动继承id参数。
方式2:绝对路由
如果更倾向于绝对路径,可以明确拼接id参数:
<a class="ui labeled positive icon small button" [routerLink]="['/Questionaire', route.snapshot.paramMap.get('id'), 'ModifyMetaContent', '', questionnaireTitle]"> <i class="plus icon"></i> new metaContent </a>
3. 优化返回按钮逻辑,避免硬编码路径
不要直接使用previousState的硬编码路径,而是利用Angular Router的相对导航来返回,这样会自动保留父级参数。在ModifyMetaContentComponent中注入Router和ActivatedRoute:
import { Router, ActivatedRoute } from '@angular/router'; constructor(private router: Router, private route: ActivatedRoute) {} goBack() { // 跳转到父级路由的MetaContentList子路由 this.router.navigate(['MetaContentList'], { relativeTo: this.route.parent }); // 或者直接用浏览器后退,状态正确的话也能保留参数 // window.history.back(); }
这样点击返回按钮时,会回到/Questionaire/:id/MetaContentList,参数完全保留,不会出现路由匹配错误。
总结
核心思路就是让需要共享参数的页面都嵌套在抽象路由Questionaire/:id下,这样URL会始终携带参数,再配合Angular的相对导航功能,就能完美解决返回时参数丢失的问题,和你之前用AngularJS UI-Router嵌套状态的思路是一致的。
内容的提问来源于stack exchange,提问作者Aref Zamani

