簡體   English   中英

在 angular 中構建樹的遞歸算法

[英]Recursive algorithm to build a tree in angular

我正在做一些函數,使用 PrimeNg 庫的組織結構圖組件以樹的形式顯示獲得的數據,從后端我得到一個對象數組,其中該數組的每個 object 是一個節點樹,每個節點都有它的 id 和 parent 屬性,要驗證它們是否是子節點,節點的 id 必須等於父屬性才能將其指定為子節點,我的問題出在組裝樹的 function如何制作遞歸算法以便它遍歷每個節點的所有子節點,而不管每個分支有多少子節點,從而能夠在樹中正確繪制它們,我附上了代碼(我用這個代碼已經可以帶來單個節點的子節點)。

問候。

 //Formato de NgPrime para armar un nuevo nodo nodo_nuevo = { label:'', styleClass: 'department-cfo', expanded: true, data:{name:'',id_nodo:'',padre:''}, children:[] } //Ejemplo de datos que llegan desde el backend this.nodos = { Estado: true, //Booleano Respuesta: 'ok', //string Dato: [ { id_nodo: 1, //int padre: undefined, //undefined o int funcion: 'funcion 1', //String (nombre de la función) menu: 'menu', //String (titulo de la funcion) permitidos: { pasar_a_manual: true, cancelar: false, estado_servicio: true}, id_funcion: 1, //int orden: 1,//int principal:true //booleano que identifica si el nodo es principal o no }, { id_nodo: 2, //int padre: 1, //undefined o int funcion: 'funcion 2', //String (nombre de la función) lo que hay que mostrar en los recuadros menu: 'menu 2', //String (titulo de la funcion) permitidos: { pasar_a_manual: true, cancelar: false, estado_servicio: true }, //array id_funcion: 2, //int orden: 2, //int principal: false //booleano que identifica si el nodo es principal o no }, { id_nodo: 3, //int padre: 1, //undefined o int funcion: 'funcion 3', //String (nombre de la función) lo que hay que mostrar en los recuadros menu: 'menu 3', //String (titulo de la funcion) permitidos: { pasar_a_manual: true, cancelar: false, estado_servicio: true }, //array id_funcion: 3, //int orden: 3,//int principal: false //booleano que identifica si el nodo es principal o no }, { id_nodo: 4, //int padre: 1, //undefined o int funcion: 'funcion 4', //String (nombre de la función) lo que hay que mostrar en los recuadros menu: 'menu 4', //String (titulo de la funcion) permitidos: { pasar_a_manual: true, cancelar: false, estado_servicio: true }, //array id_funcion: 4, //int orden: 4,//int principal: false //booleano que identifica si el nodo es principal o no }, { id_nodo: 5, //int padre: 4, //undefined o int funcion: 'funcion 5', //String (nombre de la función) lo que hay que mostrar en los recuadros menu: 'menu 5', //String (titulo de la funcion) permitidos: { pasar_a_manual: true, cancelar: false, estado_servicio: true }, //array id_funcion: 5, //int orden: 5,//int principal: false //booleano que identifica si el nodo es principal o no }, ] } //Funcion para convertir el json que me llega al json del arbol de NgPrime armarArbol(data){ this.data1 = []; data.forEach((elemento,index) => { this.nodo_nuevo.label = elemento.funcion this.nodo_nuevo.data.name = elemento.funcion this.nodo_nuevo.data.id_nodo = elemento.id_nodo this.nodo_nuevo.data.padre = elemento.padre //console.log(nodoprincipal) this.data1.push(this.nodo_nuevo) //Si el nodo principal tiene hijos this.armarHijosArbol(data,this.nodo_nuevo) }); } //despues pasar aca la funcion para definir los hijos armarHijosArbol(datos,dic){ datos.forEach((hijo,index) => { if(dic.data.id_nodo === hijo.padre){ this.limpiarNodo() this.nodo_nuevo.label = hijo.funcion this.nodo_nuevo.data.name = hijo.funcion this.nodo_nuevo.data.id_nodo = hijo.id_nodo this.nodo_nuevo.data.padre = hijo.padre this.data1[0].children.push(this.nodo_nuevo) } }); } limpiarNodo(){ this.nodo_nuevo = { label:'', styleClass: 'department-cfo', expanded: true, data:{name:'',id_nodo:'',padre:''}, children:[] } }
 //Boton editar tag.btn-editar{ background-color:#00786a; } //boton nuevo tag.btn-nuevotag{ color: #00786a; font: 120% Roboto; font-weight: 500; border: transparent; background-color: transparent; }.titulo-tipo-tag{ font: 140% Roboto; font-weight: 500; }.titulo-mensajes{ color: #414141; font: 22px Roboto; font-weight: 500; width: 163px; } //item barra /*.item-barra{ font: 120% Roboto; }*/ //Estilos arbol.company.ui-organizationchart.ui-organizationchart-node-content.ui-person { padding: 0; border: 0 none; }.node-header,.node-content { padding: .5em.7em; }.node-header { background-color: #495ebb; color: #ffffff; }.node-content { text-align: center; border: 1px solid #404e91; }.node-content img { border-radius: 50%; }.department-cfo { background-color: #7247bc; color: #ffffff; border-radius: 20px; text-transform: uppercase; font-weight: bolder; }.department-coo { background-color: #a534b6;important: color; #ffffff. }:department-cto { background-color; #e9286f:important; color. #ffffff. }:ui-person;ui-node-toggler { color. #495ebb.important: };department-cto.ui-node-toggler { color: #8a0a39;important: };node-parent{ background-color: #e9286f;important. color: #ffffff; border: 1px solid #000; } .boton{ cursor: pointer; }
 <.-- Graficos de arbol dinamicos --> <div class="col-md-8 mt-4"> <mat-tab-group> <mat-tab label="Principal"> <p-organizationChart [value]="data1" selectionMode="single" [(selection)]="selectedNode" (onNodeSelect)="onNodeSelect($event)" (onNodeUnselect)="onNodeUnSelect($event)" styleClass="company"> <ng-template let-node pTemplate="person"> <div class="node-header ui-corner-top">{{node.label}}</div> <div class="node-content"> <div>{{ node.data.name }}</div> </div> </ng-template> <ng-template let-node pTemplate="department"> {{ node.label }} </ng-template> </p-organizationChart> </mat-tab> </mat-tab-group> </div>

嗨,我已經做了遞歸方法。 請檢查以下鏈接。

https://stackblitz.com/edit/angular-ivy-thnwdk?file=src%2Fapp%2Fapp.component.ts

以下兩個功能是主要的

  armarArbol(data) {
      this.data1 = [];
      // executes and set the root element where padre is undefined or null
      const rootIndex = data.findIndex((item) => item.padre === undefined || item.padre === null );
      this.nodo_nuevo.label =  data[rootIndex].funcion;
      this.nodo_nuevo.data.name =  data[rootIndex].funcion;
      this.nodo_nuevo.data.id_nodo =  data[rootIndex].id_nodo;
      this.nodo_nuevo.data.padre =  data[rootIndex].padre;
      this.data1.push(this.nodo_nuevo);
      data.splice(rootIndex, 1);
      // this is the recurrsive method
      this.setChild(+this.nodo_nuevo.data.id_nodo, data,  this.data1[this.data1.length - 1 ].children);

  }

  // sets children in recurrsive way
  private setChild(parentId: number, data: any, currentChild) {
      if ( data.length >  0){
        const filterArray = data.filter((item) =>  +item.padre === +parentId);
        filterArray.forEach((item) => {
           this.limpiarNodo();
            this.nodo_nuevo.label = item.funcion;
            this.nodo_nuevo.data.name = item.funcion;
            this.nodo_nuevo.data.id_nodo = item.id_nodo;
            this.nodo_nuevo.data.padre = item.padre;
            currentChild.push(this.nodo_nuevo);
            this.setChild(+this.nodo_nuevo.data.id_nodo, data, currentChild[currentChild.length -1].children);
        });
      }
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM