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

Angular中如何将JSON数据转换为适配PrimeNG TreeNode接口的树形结构

多级权限数据转PrimeNG TreeNode树形结构解决方案

问题背景

需要将API返回的多级权限数据转换为适配PrimeNG TreeNode接口的树形结构,现有实现仅支持父节点和一级子节点,无法处理二级及以上层级的子节点。

PrimeNG TreeNode接口定义

export interface TreeNode {
    label?: string;
    data?: any;
    icon?: any;
    expandedIcon?: any;
    collapsedIcon?: any;
    children?: TreeNode[];
    leaf?: boolean;
    expanded?: boolean;
    type?: string;
    parent?: TreeNode;
    partialSelected?: boolean;
    styleClass?: string;
    draggable?: boolean;
    droppable?: boolean;
    selectable?: boolean;
    key?: string;
}

API返回数据格式

"result": [
    {
      "permissionName": "Roles",
      "level": 2,
      "selectable": true,
      "children": [
        {
          "permissionName": "Roles.Create",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Roles.Edit",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Roles.Delete",
          "level": 3,
          "selectable": true,
          "children": []
        }
      ]
    },
     {
      "permissionName": "Users",
      "level": 2,
      "selectable": true,
      "children": [
        {
          "permissionName": "Users.Create",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Users.Edit",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Users.Delete",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Users.ChangePermissions",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Users.Impersonation",
          "level": 3,
          "selectable": true,
          "children": []
        },
        {
          "permissionName": "Users.Unlock",
          "level": 3,
          "selectable": true,
          "children": []
        }
      ]
    }
]

现有问题代码

let permissionResult = resultFromAPI;
//  let childrenArray: TreeNode[] = [];
for(var i= 0; i< permissionResult.permissions.length;i++){
    this.treeData.push({
        label:permissionResult.permissions[i].permissionName,
        icon: 'pi pi-folder',
        data:permissionResult.permissions[i].permissionName,
        children: this.childrenArrayfunction(permissionResult.permissions[i].children)
    })

    if (permissionResult.permissions[i].selected) {
        this.grantedPermissionNames.push(permissionResult.permissions[i].permissionName)
    }
}

childrenArrayfunction(resultArray:any[]=[]){
    let childArray: TreeNode[]=[];
    if(resultArray.length > 0){
        for(var j= 0; j< resultArray.length;j++){
            childArray.push({
                label:resultArray[j].permissionName,
                data:resultArray[j].permissionName,
                icon: 'pi pi-folder',
            })
        }
    }
    return childArray;
}

上述代码仅处理一级子节点,未递归处理子节点的子节点,无法支持多级树形结构。

解决方案:递归转换函数

使用递归函数处理树形结构,可适配任意层级的权限数据转换:

核心转换函数

import { TreeNode } from 'primeng/api';

// 递归转换单个权限节点为TreeNode
convertPermissionToTreeNode(permission: any): TreeNode {
    // 映射基础属性
    const treeNode: TreeNode = {
        label: permission.permissionName,
        data: permission.permissionName,
        icon: 'pi pi-folder',
        selectable: permission.selectable,
        leaf: permission.children.length === 0 // 无子节点标记为叶子节点
    };

    // 递归处理子节点
    if (permission.children && permission.children.length > 0) {
        treeNode.children = permission.children.map(child => this.convertPermissionToTreeNode(child));
    }

    return treeNode;
}

// 批量转换权限列表为TreeNode数组
convertPermissionsToTreeNodes(permissions: any[]): TreeNode[] {
    return permissions.map(permission => this.convertPermissionToTreeNode(permission));
}

使用方式

let permissionResult = resultFromAPI;
// 转换整个权限列表为树形结构
this.treeData = this.convertPermissionsToTreeNodes(permissionResult.permissions);

// 递归收集所有选中的权限名称(如果需要)
this.grantedPermissionNames = [];
permissionResult.permissions.forEach(permission => {
    this.collectSelectedPermissions(permission);
});

// 递归收集选中权限的辅助函数
collectSelectedPermissions(permission: any) {
    if (permission.selected) {
        this.grantedPermissionNames.push(permission.permissionName);
    }
    // 递归处理子节点的选中状态
    if (permission.children && permission.children.length > 0) {
        permission.children.forEach(child => this.collectSelectedPermissions(child));
    }
}

方案说明

  • 递归函数convertPermissionToTreeNode会处理当前节点的属性映射,并对每个子节点重复调用自身,实现任意层级的转换。
  • 通过leaf属性标记叶子节点,优化PrimeNG树组件的渲染逻辑。
  • 同步实现了递归收集选中权限的逻辑,确保所有层级的选中权限都能被正确收集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:44:58