Angular父路由routerLinkActive在动态子路由切换时失效问题
问题描述
我有如下父路由组件:
@Component({ selector: 'app-layout', standalone: true, imports: [CommonModule, RouterModule], templateUrl: './layout.component.html', styleUrl: './layout.component.css', template: ` <ul> @for (project of projects; track project.id) { <li> <a class="link" [routerLink]="['projects', project.id, project.defaultView]" routerLinkActive="active" >{{ project.name }}</a > </li> } </ul> ` }) export default class LayoutComponent { projects = [ { id: 1, name: 'My awesome project', defaultView: 'overview' }, { id: 2, name: 'App v1.0', defaultView: 'calendar' }, ]; }
点击父链接可跳转到对应默认子路由,父链接会自动添加active类。但点击子路由组件(如下方app-project)中的链接(比如Calendar)时:
@Component({ selector: 'app-project', standalone: true, imports: [CommonModule, RouterModule], templateUrl: './project.component.html', styleUrl: './project.component.css', template: ` <ul> <li> <a class="link" [routerLink]="['overview']" routerLinkActive="active" >Overview</a > </li> <li> <a class="link" [routerLink]="['calendar']" routerLinkActive="active" >Calendar</a > </li> <li> <a class="link" [routerLink]="['settings']" routerLinkActive="active" >Settings</a > </li> </ul> <router-outlet></router-outlet> ` }) export default class ProjectComponent implements OnInit { projectId!: string; constructor(private route: ActivatedRoute) {} ngOnInit(): void { this.route.params.pipe(tap(({ id }) => (this.projectId = id))).subscribe(); } }
父链接的active类会被移除。如何在保留[routerLink]="['projects', project.id, project.defaultView]"默认子路由导航的前提下,让父链接始终保持active类?
解决方案
方法一:配置routerLinkActiveOptions取消精确匹配
Angular的routerLinkActive默认采用精确匹配:只有当前URL和routerLink的路径完全一致时,才会保留active类。当跳转到项目下的其他子路由(比如/projects/1/calendar),路径和父链接的/projects/1/overview不一致,所以active类会被移除。
只需给父链接添加routerLinkActiveOptions,设置exact: false即可让它以前缀匹配的方式激活:
<a class="link" [routerLink]="['projects', project.id, project.defaultView]" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: false }" > {{ project.name }} </a>
这样一来,只要当前路由的URL包含父链接的路径前缀(比如/projects/1/开头的任意子路由),父链接就会保持active类,同时不影响原有的默认子路由跳转行为。
方法二:手动根据项目ID判断激活状态
如果需要更精准的控制,也可以直接基于当前路由中的项目ID来手动绑定active类,完全脱离默认子路由的路径限制:
步骤1:修改父组件的模板
<a class="link" [routerLink]="['projects', project.id, project.defaultView]" [class.active]="isCurrentProject(project.id)" > {{ project.name }} </a>
步骤2:在父组件中添加判断逻辑
import { ActivatedRoute } from '@angular/router'; export default class LayoutComponent { projects = [ { id: 1, name: 'My awesome project', defaultView: 'overview' }, { id: 2, name: 'App v1.0', defaultView: 'calendar' }, ]; constructor(private route: ActivatedRoute) {} isCurrentProject(projectId: number): boolean { // 获取当前激活子路由中的项目ID参数 const currentId = this.route.firstChild?.snapshot.params.get('id'); return currentId === projectId.toString(); } }
这个方法通过直接对比当前路由的id参数和项目ID,来决定是否添加active类,无论当前跳转到项目下的哪个子路由,只要ID匹配,父链接就会保持激活状态。
内容的提问来源于stack exchange,提问作者Sandeep K Nair
相关产品推荐
相关产品推荐

