Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use component in itself recursively to create a tree

Do you know is it possible to use component in itself? If yes,where to read about it?

I have next situation: have list of mainItems, every Main Item has subItem (the same look like mainItem), every subItem can have it's own subItem etc. So it better to use nesting,but how?

like image 370
Serhiy Avatar asked Jun 10 '16 10:06

Serhiy


2 Answers

update

forwardRef() isn't required anymore because directives was moved to NgModule.declarations and therefore recursive components don't need to be registered on themselves as directives anymore.

Angular 4.x.x Plunker example

original

That supported. You just need to add the component to directives: [] in its @Component() decorator. Because the decorator comes before the class and classes can't be referenced before they are declared forwardRef() is necessary.

import {Component, forwardRef, Input} from '@angular/core'  @Component({   selector: 'tree-node',   template: `   <div>{{node.name}}</div>   <ul>     <li *ngFor="let node of node.children">       <tree-node  [node]="node"></tree-node>     </li>   </ul> ` }) export class TreeNode {   @Input() node; } 
@Component({   selector: 'my-app',   template: `     <div>       <h2>Hello {{name}}</h2>       <tree-node [node]="node"></tree-node>     </div>   `,   directives: [TreeNode] }) export class App {   constructor() {     this.name = 'Angular2 (Release Candidate!)'   }    node = {name: 'root', children: [     {name: 'a', children: []},     {name: 'b', children: []},     {name: 'c', children: [       {name: 'd', children: []},       {name: 'e', children: []},       {name: 'f', children: []},      ]},   ]};   } 

Angular 2.0.0-beta.x Plunker example

See also Inject parent component of the same type as child component

like image 93
Günter Zöchbauer Avatar answered Sep 20 '22 16:09

Günter Zöchbauer


using ng-template is the best solution to solve recursive DOM problems.

@Component({   selector: 'tree-node',    template: `      <ng-container *ngTemplateOutlet="tree;context:{node:node}">      </ng-container>       <ng-template #tree let-node="node">        <div>{{node.name}}</div>        <ul *ngIf="node.children && node.children.length > 0">          <ng-container *ngFor="let child of node.children">            <li>              <ng-container *ngTemplateOutlet="tree;context:{node:child}">              </ng-container>            </li>          </ng-container>        </ul>      </ng-template>    ` }) export class TreeNode {     @Input() node; } 

No needs to add the component to directives: [] in its @Component().

@Component({   selector: 'my-app',   template: `     <div>       <h2>Hello {{name}}</h2>       <tree-node [node]="node"></tree-node>     </div>   ` }) export class App {    node = {     name: 'root', children: [       { name: 'a', children: [] },       {         name: 'b', children: [           { name: 'b-1', children: [] },           {             name: 'b-2', children: [               { name: 'b-2-1', children: [] },               { name: 'b-2-2', children: [] },               { name: 'b-2-3', children: [] }             ]           }         ]       },       {         name: 'c', children: [           { name: 'c-1', children: [] },           { name: 'c-2', children: [] }         ]       },     ]   };  } 

Output:

  • root
    • a
    • b
      • b-1
      • b-2
        • b-2-1
        • b-2-2
        • b-2-3
    • c
      • c-1
      • c-2

HTML:

<tree-node>     <div>root</div>     <ul>         <li>             <div>a</div>         </li>         <li>             <div>b</div>             <ul>                 <li>                     <div>b-1</div>                 </li>                 <li>                     <div>b-2</div>                     <ul>                         <li>                             <div>b-2-1</div>                         </li>                         <li>                             <div>b-2-2</div>                         </li>                         <li>                             <div>b-2-3</div>                         </li>                     </ul>                 </li>             </ul>         </li>         <li>             <div>c</div>             <ul>                 <li>                     <div>c-1</div>                 </li>                 <li>                     <div>c-2</div>                 </li>             </ul>         </li>     </ul> </tree-node> 
like image 32
Pedram A. Keyvani Avatar answered Sep 23 '22 16:09

Pedram A. Keyvani