Angular侧边栏所有菜单项如何获取当前选中ID用于routerLink传参
实现方案
方案1:直接从路由提取ID(推荐,无需额外状态管理)
侧边栏组件可以直接监听路由变化,从当前URL的参数中提取项目ID,和你现有逻辑完全适配,不需要修改项目点击跳转的原有代码:
首先在侧边栏组件中引入依赖并订阅路由事件:
import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { filter, takeUntil } from 'rxjs'; import { Subject } from 'rxjs/internal/Subject'; @Component({ selector: 'app-sidebar', templateUrl: './sidebar.component.html' }) export class SidebarComponent implements OnInit, OnDestroy { id: string | null = null; private destroy$ = new Subject<void>(); constructor( private route: ActivatedRoute, private router: Router ) {} ngOnInit(): void { // 监听所有导航结束事件,实时更新ID this.router.events.pipe( filter(event => event instanceof NavigationEnd), takeUntil(this.destroy$) ).subscribe(() => { // 递归遍历子路由,获取携带的ID参数 let activeRoute = this.route.firstChild; while (activeRoute) { const projectId = activeRoute.snapshot.paramMap.get('id'); if (projectId) { this.id = projectId; break; } activeRoute = activeRoute.firstChild; } }) } ngOnDestroy(): void { // 销毁订阅,避免内存泄漏 this.destroy$.next(); this.destroy$.complete(); } }
模板部分直接复用你写的routerLink逻辑即可,ID不存在时可以选择隐藏菜单或者跳转项目选择页:
<a [routerLink]="['/addresses/', id]" *ngIf="id">Addresses</a> <a [routerLink]="['/reports/', id]" *ngIf="id">Reports</a>
方案2:通过全局共享服务存储ID(适合多组件复用ID的场景)
如果你的应用里多个组件都需要用到选中的项目ID,可以用根级别注入的服务全局存储这个值,避免重复从路由取数:
- 首先新建全局共享服务
project.service.ts
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ProjectService { // 用BehaviorSubject缓存选中的项目ID,默认值为null private readonly selectedId$ = new BehaviorSubject<string | null>(null); public selectedId = this.selectedId$.asObservable(); setSelectedId(id: string): void { this.selectedId$.next(id); } }
- 在你点击项目列表跳转的逻辑里,调用服务存ID:
// 项目列表行点击事件 onProjectClick(projectId: string) { this.projectService.setSelectedId(projectId); this.router.navigate(['/project/', projectId]); }
- 侧边栏组件订阅服务中的ID即可:
import { Component, OnDestroy, OnInit } from '@angular/core'; import { ProjectService } from './project.service'; import { takeUntil } from 'rxjs'; import { Subject } from 'rxjs/internal/Subject'; @Component({ selector: 'app-sidebar', templateUrl: './sidebar.component.html' }) export class SidebarComponent implements OnInit, OnDestroy { id: string | null = null; private destroy$ = new Subject<void>(); constructor(private projectService: ProjectService) {} ngOnInit(): void { this.projectService.selectedId.pipe( takeUntil(this.destroy$) ).subscribe(id => { this.id = id; }) } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
注意事项
- 如果你的路由配置中项目ID的参数名不是
id,请把paramMap.get('id')中的参数名替换成实际配置的字段 - 使用服务存储的方案如果需要兼容页面刷新场景,可以搭配localStorage缓存ID,或者在应用初始化时从当前路由提取ID写入服务
内容的提问来源于stack exchange,提问作者Denz
相关产品推荐
相关产品推荐

