后端返回嵌套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等信息取出 } }