You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:04:59