Angular Material嵌套树无法显示,请求技术帮助
问题排查与修复方案
1. hasChild方法缺失返回值
你的hasChild方法仅执行了判断逻辑,但未返回结果,导致Angular Tree无法识别节点是否包含子节点,嵌套节点无法正确渲染。
修复代码:
hasChild = (_: number, node: WorkingTreeNode) => { const hasChild = !!node.children && node.children.length > 0; console.log("hasAChild", hasChild); return hasChild; // 必须返回判断结果 }
2. 异步请求时序错误
buildWorkingTree中存在多层嵌套异步请求,你在ngOnInit调用buildWorkingTree后立刻给dataSource.data赋值,此时workingTree仍是空数组(HTTP请求未完成)。同时内部子节点请求(数据集、风险评估)也是异步的,导致父节点被push到workingTree时,子节点数组还未填充数据。
修复方案:用RxJS操作符处理异步流
避免嵌套subscribe,改用switchMap、forkJoin组合请求,确保所有数据加载完成后再赋值给dataSource:
import { forkJoin } from 'rxjs'; import { switchMap, map } from 'rxjs/operators'; // ... public buildWorkingTree(userId: string): void { this.projectService.getUserProjects(userId).pipe( switchMap(projects => { // 为每个项目获取对应数据集 const projectObservables = projects.map(project => { return this.datasetService.getProjectDatasets(project.id).pipe( switchMap(datasets => { // 为每个数据集获取对应风险评估 const datasetObservables = datasets.map(dataset => { return this.riskAssessmentService.getDatasetRiskAssessments(dataset.id).pipe( map(riskAssessments => { return { name: dataset.name, id: dataset.id, children: riskAssessments.map(ra => ({ name: ra.name, id: ra.id, children: [] })) }; }) ); }); return forkJoin(datasetObservables).pipe( map(datasetNodes => { return { name: project.name, id: project.id, children: datasetNodes }; }) ); }) ); }); return forkJoin(projectObservables); }) ).subscribe( treeNodes => { this.workingTree = treeNodes; this.dataSource.data = this.workingTree; // 所有数据加载完成后赋值 console.log("完整树形数据", this.workingTree); }, error => { alert(error.message); } ); }
修改ngOnInit,移除提前赋值的逻辑:
ngOnInit() { this.userId = this.tokenStorageService.getUser().id; this.buildWorkingTree(this.userId); }
3. 检查样式是否完善
确保working-tree.component.css中包含官方示例所需样式:
.example-tree-invisible { display: none; } .example-tree ul, .example-tree li { margin-top: 0; margin-bottom: 0; list-style-type: none; }
4. 模块导入检查
确认组件所在模块已导入必要的Angular Material模块:
import { MatTreeModule } from '@angular/material/tree'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; @NgModule({ imports: [ // ... MatTreeModule, MatIconModule, MatButtonModule ] }) export class YourModule { }
内容的提问来源于stack exchange,提问作者Anita
相关产品推荐
相关产品推荐

