You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ASP.NET Core Angular 5.x多级菜单嵌套展开异常问题排查

解决AppMenuItem多级子菜单无法折叠展开的问题

我懂你现在的困扰——用AppMenuItem搭建嵌套菜单时,一级子菜单能正常收放,但再深一层的子菜单就完全没反应了。先看了你贴的菜单结构代码,数据层级是没问题的,问题大概率出在菜单渲染组件的逻辑上,没处理好多级嵌套的情况。

可能的原因

  1. 菜单组件只做了单层渲染:默认的实现可能只遍历了一级children,没有递归渲染更深层级的子菜单;
  2. 展开状态没有独立维护:可能只给一级菜单绑定了展开状态,深层菜单没有自己的状态标识,导致点击没反应。

解决方案

下面分步骤来修复,假设你用的是Angular(从代码里的路径和命名风格看很像ABP框架的结构):

1. 改成递归渲染的菜单组件

首先要让菜单组件能递归渲染子菜单,模板里要这么写:

<!-- 父菜单组件模板 -->
<div class="menu-container">
  <ng-container *ngFor="let item of menuItems">
    <div class="menu-item" (click)="toggleExpand(item)">
      <i class="{{ item.icon }}"></i>
      <span>{{ item.displayName }}</span>
      <!-- 有子菜单时显示折叠/展开图标 -->
      <span class="expand-icon" *ngIf="hasChildren(item)">
        {{ isExpanded(item) ? '▼' : '▶' }}
      </span>
    </div>
    <!-- 递归渲染子菜单,只有展开时才显示 -->
    <div class="sub-menu" *ngIf="hasChildren(item) && isExpanded(item)">
      <app-menu-item [menuItems]="item.children"></app-menu-item>
    </div>
  </ng-container>
</div>

这里的关键是<app-menu-item [menuItems]="item.children"></app-menu-item>,通过递归调用自身组件来渲染深层子菜单。

2. 为每个菜单节点维护独立的展开状态

之前如果是用单个变量控制展开,现在要换成用Map来存储每个节点的状态,确保每个层级互不干扰:

// 菜单组件的类文件
import { Component, Input } from '@angular/core';
import { AppMenuItem } from './app-menu-item';

@Component({
  selector: 'app-menu-item',
  templateUrl: './app-menu-item.component.html',
  styleUrls: ['./app-menu-item.component.css']
})
export class AppMenuItemComponent {
  @Input() menuItems: AppMenuItem[] = [];
  // 用permissionName作为唯一key,存储每个菜单的展开状态
  private expandedStates = new Map<string, boolean>();

  toggleExpand(item: AppMenuItem): void {
    if (!this.hasChildren(item)) return;
    const key = item.permissionName;
    const currentState = this.expandedStates.get(key) || false;
    this.expandedStates.set(key, !currentState);
  }

  isExpanded(item: AppMenuItem): boolean {
    return this.expandedStates.get(item.permissionName) || false;
  }

  hasChildren(item: AppMenuItem): boolean {
    return !!item.children && item.children.length > 0;
  }
}

3. 确认AppMenuItem类的定义正确

确保你的AppMenuItem类里的children属性是AppMenuItem[]类型,这样递归渲染时类型才匹配:

export class AppMenuItem {
  constructor(
    public displayName: string,
    public permissionName: string,
    public icon: string,
    public route: string,
    public children?: AppMenuItem[] // 这里必须是AppMenuItem数组
  ) {}
}

4. 测试你的菜单数据

保持你原来的getMenu()方法不变,现在组件应该能递归识别所有层级的子菜单,并且每个节点都有自己的展开状态了。

总结

核心就是两个点:让菜单组件递归渲染子菜单,给每个节点单独维护展开状态。按照上面的步骤改完,应该就能让所有层级的子菜单都正常折叠展开了。

内容的提问来源于stack exchange,提问作者hadie

火山引擎 最新活动