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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:36:02