微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

angular中如何将后端返回的多层嵌套json数据转换成树状层级结构

后端返回嵌套json数据的方法见我的另一篇博客https://www.cnblogs.com/wwwzgy/p/15561613.html

返回的是一个多层嵌套式的json,示例格式如下,这是一个公司的部门架构,可以无限多层嵌套。

[
    {"id":"0000000001",
      "name":"总公司",
      "parent_id":"0",
      "operate_time":"2021-11-15 20:46:12",
      "children":[
                        {"id":"0100000000",
                          "name":"分公司1",
                          "parent_id":"0000000001",
                           "children":[
                                            {"id":"0101000000",
                                               "name":"部门1",
                                              "parent_id":"0100000000",
                                              "children":[]},
                                            {"id":"0102000000",
                                              "name":"部门2", 
                                              "parent_id":"0100000000",
                                              "children":[]}
                                            ]
                         },
                         {"id":"0200000000",
                            "name":"分公司2",
                            "parent_id":"0000000001",
                             "children":[]
                          }
                    ]
        }
]             

前端的展示效果如下图所示:

 前端的html页面,参考ant design给出的模板代码。仅改变其中一句:<a (click)="search(node.name)"> {{ node.name }}</a>

末尾是为了考虑本html页面在实际运用中是一个弹出框,所以增加了“取消”和“确定”两个按钮,以及为了获得后台数据的链接(根据实际情况,可改成自动获取数据)。

<div class="edituser-dialog">
    <nz-tree-view [nzTreeControl]="treeControl" [nzDataSource]="dataSource">
        <nz-tree-node *nzTreeNodeDef="let node" nzTreeNodePadding>
          <nz-tree-node-toggle nzTreeNodeNoopToggle></nz-tree-node-toggle>
          <nz-tree-node-option
            [nzdisabled]="node.disabled"
            
            (nzClick)="selectListSelection.toggle(node)"
          >
            <a (click)="search(node.name)">{{ node.name }}</a>
          </nz-tree-node-option>
        </nz-tree-node>
  
        <nz-tree-node *nzTreeNodeDef="let node; when: hasChild" nzTreeNodePadding>
          <nz-tree-node-toggle>
            <i nz-icon nzType="caret-down" nzTreeNodetoggleRotateIcon></i>
          </nz-tree-node-toggle>
          <nz-tree-node-option
            [nzdisabled]="node.disabled"
            
            (nzClick)="selectListSelection.toggle(node)"
          >
          <a (click)="search(node.name)"> {{ node.name }}</a>
          </nz-tree-node-option>
        </nz-tree-node>
    </nz-tree-view>
    
    <div><a (click)="getorganization()">获取部门数据</a></div>

    <div class="edituser-dialog-footer">
      <button nz-button nzSize="large" style="margin-right: 10px;" [nzType]="'default'"
        (click)="handleCancel()">取消</button>
      <button nz-button nzSize="large" [nzType]="'primary'" (click)="handleConfirm()">确定</button>
    </div>
</div>
View Code

ts的代码,也是参考ant design给出的模板代码增加getorganization()方法以及transferData()方法,getorganization()是获取后台是json数据,transferData()则是将json数据转换成前端要求的TreeNode类型数据,其中采用了递归的方法实现转换。

interface TreeNode {
  name: string;
  disabled?: boolean;
  children?: TreeNode[];
}

var TREE_DATA: TreeNode[] = [];

interface FlatNode {
  expandable: boolean;
  name: string;
  level: number;
  disabled: boolean;
}

@Component({
  selector: 'app-department',
  templateUrl: './department.component.html',
  styleUrls: ['./department.component.less'],
})
export class DepartmentComponent implements OnInit {

  ngOnInit(): void {
  }


  organizationTree: TreeNode[]=[];

  constructor(private http: HttpClient,private subject: NzModalRef,) {
    this.dataSource.setData(TREE_DATA);
    this.treeControl.expandAll();
  }

  private transformer = (node: TreeNode, level: number): FlatNode => ({
    expandable: !!node.children && node.children.length > 0,
    name: node.name,
    level,
    disabled: !!node.disabled
  });
  selectListSelection = new SelectionModel<FlatNode>(true);

  treeControl = new FlatTreeControl<FlatNode>(
    node => node.level,
    node => node.expandable
  );

  treeFlattener = new NzTreeFlattener(
    this.transformer,
    node => node.level,
    node => node.expandable,
    node => node.children
  );

  dataSource = new NzTreeFlatDataSource(this.treeControl, this.treeFlattener);

  hasChild = (_: number, node: FlatNode): boolean => node.expandable;

  search(name:string):void{
    console.log(name);
  }

  getorganization():void{
    this.http.post("api/department", {
    responseType: "json",
    headers: new HttpHeaders().append("Content-Type", "application/json")
                              .append('Authorization', 'Bearer '+localStorage.getItem("token"))
    }).subscribe(       
        res=> { 
          console.log(res);
          this.transferData(res,this.items);
          TREE_DATA=this.items;
          this.dataSource.setData(TREE_DATA);          
        }
      );
  }
  items: TreeNode[]=[];
  transferData(jsonList:any,items:TreeNode[]):void{      
      for(let i=0; i<jsonList.length; i++){
        var node: TreeNode={name:"",disabled:false,children:[]};
        items.push(node);
        if(jsonList[i].children.length>0){
          this.transferData(jsonList[i].children,items[i].children);
        }
        items[i].name=jsonList[i].name;
      }
  }

  handleCancel():void{
    this.subject.destroy('onCancel');
  }
  handleConfirm():void{

  }
}
View Code

transferData()详解:

items: TreeNode[]=[];   //构造一个空数组,用于存放最终结果
  transferData(jsonList:any,items:TreeNode[]):void{      //jsonList就是后端返回的json数组
      for(let i=0; i<jsonList.length; i++){  //循环遍历后端返回的jsonList中的每个json数据
        var node: TreeNode={name:"",disabled:false,children:[]};  //构造一个空的TreeNode数据,此句必须放在循环体里
        items.push(node);
        if(jsonList[i].children.length>0){  //如果jsonList有下一层
          this.transferData(jsonList[i].children,items[i].children);  //递归找到下一层的json
        }
        items[i].name=jsonList[i].name;  //取出部门名字,根据需要也可以把部门id等信息取出
      }
  }

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐