Angular中如何将含相同元素的数据合并为树形结构展示
Angular MatTree 树形数据聚合适配方案
你需要修改接口返回数据的组装逻辑,先做同层级节点聚合,再按规则生成树形结构,修改后代码如下:
getQualifyParams() { const perm = { id: "133", username: "John", }; this.article.qualifyTheArticle(perm).subscribe( (res) => { const value = res.result; // 一级节点Map:key为label唯一id,value为label节点 const labelMap = new Map<number, any>(); value.forEach((val) => { // 兼容接口返回label主键字段不一致的问题 const labelId = val.labelid ?? val.id; const labelName = val.label; const dd1Id = val.dd1id; const dd1Name = val.dd1; // 聚合相同label的一级节点 if (!labelMap.has(labelId)) { labelMap.set(labelId, { name: labelName, id: labelId, // 临时存储dd1的Map用于聚合,后续转成children数组 dd1Map: new Map<number, any>(), children: [] }); } const currentLabelNode = labelMap.get(labelId); // 聚合相同dd1的二级节点 if (!currentLabelNode.dd1Map.has(dd1Id)) { currentLabelNode.dd1Map.set(dd1Id, { name: dd1Name, id: dd1Id, children: [] }); } const currentDd1Node = currentLabelNode.dd1Map.get(dd1Id); // dd2有值时才挂载为三级节点 if (val.dd2 != null) { currentDd1Node.children.push({ name: val.dd2, id: val.dd2id }); } }); // 转换临时Map为最终树形结构 const treeData = Array.from(labelMap.values()).map(labelNode => { // 把dd1的Map转成children数组 labelNode.children = Array.from(labelNode.dd1Map.values()); // 删除临时属性 delete labelNode.dd1Map; return labelNode; }); this.dataSource.data = treeData; }, (err) => { console.log(err); } ); }
关键逻辑说明
- 基于Map做同层级节点聚合,避免重复生成相同label/dd1的节点,时间复杂度为O(n),性能优于遍历查重方案
- 自动兼容接口返回label主键同时存在
id、labelid两种字段的异常情况 - dd2为null时不会往对应dd1的children数组中插入节点,MatTree会自动隐藏该层级
注:如果你当前使用的是
FlatTreeControl,需要额外配合transformer将上述嵌套结构转成扁平节点结构,使用NestedTreeControl可直接适配上述数据结构。
内容的提问来源于stack exchange,提问作者kate moss
相关产品推荐
相关产品推荐

