Angular动态MatMenu加载父节点而非子节点问题求助
核心问题拆解
- 根节点未初始化数据:组件默认
data为空数组,根节点未传入年份列表,导致初始菜单无内容。 - HTML模板语法错误与冗余代码:存在重复按钮、属性绑定错误(
mat-menu-item ="menu"),且menuOpened事件绑定位置错误。 - 数据加载逻辑反向:
getData方法中if (this.dataLoaded)判断逻辑错误,导致首次点击不触发数据请求。 - 递归组件未传递数据:子组件未接收
data输入,子菜单无法加载学期数据。
分步修复代码
1. 根组件初始化(父组件模板)
在使用根菜单的父组件中,传入根节点数据和标记:
<app-dynamic-mat-menu [trigger]="'Períodos'" [isRootNode]="true" [data]="periodoService.rootLevelNodes" ></app-dynamic-mat-menu>
父组件需注入PeriodoService以暴露数据:
// 父组件.ts文件 import { PeriodoService } from '../shared/services/periodo.service'; constructor(public periodoService: PeriodoService) {}
2. 修复dynamic-mat-menu.html模板
移除冗余按钮,修正属性绑定,将menuOpened绑定到正确的触发器上:
<!-- 菜单触发器 --> <button *ngIf="isRootNode" mat-button [matMenuTriggerFor]="menu"> {{ trigger }} </button> <button *ngIf="!isRootNode" mat-menu-item [matMenuTriggerFor]="menu" (menuOpened)="getData(trigger)"> {{ trigger }} </button> <mat-menu #menu="matMenu"> <ng-container *ngFor="let node of data; let i = index"> <!-- 递归渲染可展开的年份节点 --> <button mat-menu-item *ngIf="isExpandable(node)"> <app-dynamic-mat-menu [trigger]="node" [isRootNode]="false" [data]="[]" ></app-dynamic-mat-menu> </button> <!-- 渲染不可展开的学期叶子节点 --> <button mat-menu-item *ngIf="!isExpandable(node)">{{ node }}</button> </ng-container> </mat-menu>
3. 修复dynamic-mat-menu.ts的数据加载逻辑
将判断条件改为!this.dataLoaded,确保首次点击触发数据请求:
getData(node: string) { if (!this.dataLoaded) { this.isLoading = true; this.periodoService.getChildren(node).subscribe((d) => { this.data = d?.slice() || []; this.isLoading = false; this.dataLoaded = true; }); } }
4. 优化PeriodoService的空值处理
为避免返回undefined,在getChildren中添加空数组兜底:
getChildren(node: string) { return of(this.dataMap.get(node) || []).pipe(delay(1000)); }
内容的提问来源于stack exchange,提问作者Luiza Campbell
相关产品推荐
相关产品推荐

