Angular中使用ngFor遍历如何让同标题首个菜单项在子路由时保持激活
问题原因
你当前的逻辑仅渲染每个title对应的首个菜单项,但激活状态只判断当前被渲染的菜单项自身的isActive字段,当同title的其他未被渲染的菜单项激活时,首个菜单项的isActive仍为false,因此无法触发高亮。
推荐解决方案
方案1:预处理菜单数组(最优,易维护)
把逻辑放在TS层处理,按title对菜单分组,只要分组内任意一个菜单项激活,该分组的展示项就为激活状态。
TS代码示例:
// 最终供模板渲染的处理后菜单数组 processedMenus: any[] = []; // 路由更新、菜单数组变化时调用该方法刷新状态 refreshMenus(menuArray: any[]) { const titleGroup = new Map(); menuArray.forEach(menu => { // 过滤无title的项 if (!menu.title) return; if (!titleGroup.has(menu.title)) { // 首次遇到该title,存入分组,新增分组激活状态字段 titleGroup.set(menu.title, { ...menu, groupActive: menu.isActive }) } else { // 同title分组内任意一项激活,整个分组激活状态为true const existed = titleGroup.get(menu.title); existed.groupActive = existed.groupActive || menu.isActive; } }) // 按原顺序转成数组 this.processedMenus = Array.from(titleGroup.values()); }
模板代码简化为:
<ul> <li *ngFor="let menu of processedMenus" [ngClass]="{active: menu.groupActive}"> <div>{{menu.title}}</div> </li> </ul>
方案2:模板内调用判断方法(适合菜单数量少的场景)
如果不想改动原菜单数组结构,可以在TS中新增一个按title判断激活状态的方法,模板渲染时调用:
TS代码示例:
isTitleActive(title: string): boolean { // 判断该title下是否有任意一个菜单项处于激活状态 return this.menuArray.some(item => item.title === title && item.isActive); }
模板代码调整激活条件即可:
<ul> <ng-container *ngFor="let menu of menuArray; let i=index"> <ng-container *ngIf="menu && menu.title && (i === 0 || menuArray[i-1].title !== menu.title)"> <li [ngClass]="{active: isTitleActive(menu.title)}"> <div>{{menu.title}}</div> </li> </ng-container> </ng-container> </ul>
内容的提问来源于stack exchange,提问作者Shaik Nizamuddin
相关产品推荐
相关产品推荐

