projects/rebirth-ng/src/lib/tree-view/tree-node.component.ts
| exportAs | treeNode | 
            
| selector | re-tree-node,[reTreeNode] | 
            
| styleUrls | tee-node.component.scss | 
            
| templateUrl | ./tee-node.component.html | 
            
                        Properties | 
                
                        Methods | 
                
                        Inputs | 
                
constructor(treeViewComponent: TreeViewComponent, treePanelComponent: TreePanelComponent, renderer: Renderer2)
                     | 
                ||||||||||||
| 
                             
                                    Parameters :
                                     
                    
  | 
                
                        
                        allowDraggable
                     | 
                    
                         
                            Default value:   | 
                
                        
                        allowMutipleSelected
                     | 
                    
                         
                            Default value:   | 
                
                        
                        checkable
                     | 
                    
                         
                            Default value:   | 
                
                        
                        collapseIcon
                     | 
                    |
                        
                        expendIcon
                     | 
                    |
                        
                        iconField
                     | 
                    
                             
                            Type:      | 
                
                        
                        lazyLoad
                     | 
                    
                         
                            Default value:   | 
                
                        
                        leafIcon
                     | 
                    |
                        
                        loadChildren
                     | 
                    
                             
                            Type:      | 
                
                        
                        loadingIcon
                     | 
                    
                             
                            Type:      | 
                
                        
                        node
                     | 
                    
                             
                            Type:      | 
                
                        
                        nodeCssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        nodeItemTemplate
                     | 
                    
                             
                            Type:      | 
                
                        
                        nodeItemToolbarTemplate
                     | 
                    
                             
                            Type:      | 
                
                        
                        parentNode
                     | 
                    
                             
                            Type:      | 
                
                        
                        textField
                     | 
                    
                             
                            Type:      | 
                
                        
                        valueField
                     | 
                    
                             
                            Type:      | 
                
| Private changeChildrenChecked | |||||||||
                            
                        changeChildrenChecked(nodes: any[], checked: )
                     | 
                |||||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| getNodeExpendIcon | 
getNodeExpendIcon()
                     | 
                
| 
                             
                                Returns :      
                    any
                             | 
                
| Private isDescendant | ||||||
                            
                        isDescendant(parent: , target: )
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                any
                             | 
                
| isLeaf | 
isLeaf()
                     | 
                
| 
                             
                                Returns :      
                    boolean
                             | 
                
| Private isNodeMyself | ||||||
                            
                        isNodeMyself(dropData: any)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                boolean
                             | 
                
| nodeItemCheckedChange | ||||
nodeItemCheckedChange(checked: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onChildrenNodeCheckedChange | ||||
onChildrenNodeCheckedChange(node: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onDragEnter | 
onDragEnter()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| onDragLeave | 
onDragLeave()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| onDropNodeItem | ||||
onDropNodeItem($event: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onExpendedIconClick | ||||
onExpendedIconClick($event: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onNodeItemClick | ||||
onNodeItemClick($event: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onNodeItemDbClicked | ||||
onNodeItemDbClicked($event: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| isLoading | 
                        isLoading:     
                     | 
                
                            Type :     boolean
                         | 
                    
| nodeItemContent | 
                        nodeItemContent:     
                     | 
                
                            Type :     ElementRef
                         | 
                    
                            Decorators : ViewChild
                         | 
                    
import { Component, Input, TemplateRef, ViewChild, ElementRef, Renderer2 } from '@angular/core';
import { TreeViewComponent } from './tree-view.component';
import { TreePanelComponent } from './tree-panel.component';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { DraggableDirective } from '../draggable/draggable.directive';
@Component({
  selector: 're-tree-node,[reTreeNode]',
  templateUrl: './tee-node.component.html',
  styleUrls: ['./tee-node.component.scss'],
  exportAs: 'treeNode'
})
export class TreeNodeComponent {
  @Input() node: any;
  @Input() parentNode: any;
  @Input() valueField: string;
  @Input() textField: string;
  @Input() nodeCssClass: string;
  @Input() iconField: string;
  @Input() checkable = false;
  @Input() lazyLoad = false;
  @Input() loadingIcon: string;
  @Input() loadChildren: (parent: any) => Observable<any[]>;
  @Input() allowDraggable = false;
  @Input() allowMutipleSelected = false;
  @Input() nodeItemTemplate: TemplateRef<any>;
  @Input() nodeItemToolbarTemplate: TemplateRef<any>;
  @Input() leafIcon;
  @Input() expendIcon;
  @Input() collapseIcon;
  @ViewChild('nodeItemContent') nodeItemContent: ElementRef;
  isLoading: boolean;
  isAcceptDrop = ($event) => {
    const dropData = JSON.parse($event.dataTransfer.getData(DraggableDirective.DRAGGABLE_DATA_KEY));
    if (!dropData.data.node) {
      return false;
    }
    if (this.isNodeMyself(dropData)) {
      return false;
    }
    if (this.isDescendant(dropData.data.node, this.node)) {
      return false;
    }
    return true;
  }
  constructor(private treeViewComponent: TreeViewComponent,
              private treePanelComponent: TreePanelComponent,
              private renderer: Renderer2) {
  }
  getNodeExpendIcon() {
    if (this.isLeaf()) {
      return this.leafIcon;
    }
    return this.node.$expend ? this.expendIcon : this.collapseIcon;
  }
  onExpendedIconClick($event) {
    $event.stopPropagation();
    if (this.isLeaf() || this.isLoading) {
      return;
    }
    let loadObservable = of(null);
    if (this.lazyLoad && !this.node.$loaded) {
      this.isLoading = true;
      loadObservable = this.loadChildren(this.node)
        .pipe(map((children) => {
          this.node.children = children || [];
          this.node.$loaded = true;
        }));
    }
    loadObservable.subscribe(() => {
      this.isLoading = false;
      this.node.$expend = !this.node.$expend;
      this.treeViewComponent.onNodeItemExpended(this.node);
    }, () => {
      this.isLoading = false;
    });
  }
  onNodeItemClick($event) {
    $event.stopPropagation();
    this.node.$select = !this.node.$select;
    this.treeViewComponent.onNodeItemClicked(this.node);
  }
  onNodeItemDbClicked($event) {
    this.treeViewComponent.onNodeItemDbClicked(this.node);
  }
  nodeItemCheckedChange(checked) {
    this.changeChildrenChecked(this.node.children, checked);
    this.treePanelComponent.onNodeItemCheckedChanged(this.node);
  }
  onChildrenNodeCheckedChange(node) {
    this.node.$check = !this.node.children.some((item) => !item.$check);
    this.treePanelComponent.onNodeItemCheckedChanged(node);
  }
  isLeaf() {
    if (this.lazyLoad && !this.node.$loaded) {
      return false;
    }
    return !this.node.children || !this.node.children.length;
  }
  onDragEnter() {
    this.renderer.addClass(this.nodeItemContent.nativeElement, 'drop-node-enter');
  }
  onDragLeave() {
    setTimeout(() => {
      this.renderer.removeClass(this.nodeItemContent.nativeElement, 'drop-node-enter');
    });
  }
  onDropNodeItem($event) {
    const dropData = JSON.parse($event.dataTransfer.getData(DraggableDirective.DRAGGABLE_DATA_KEY));
    if (dropData.data.node && !this.isNodeMyself(dropData)) {
      this.treeViewComponent.onNodeItemDroped({ target: this.node, data: dropData });
    }
    setTimeout(() => {
      this.renderer.removeClass(this.nodeItemContent.nativeElement, 'drop-node-enter');
    }, 0);
  }
  private isNodeMyself(dropData: any) {
    return this.node[this.valueField] === dropData.data.node[this.valueField];
  }
  private isDescendant(parent, target) {
    if (!parent) {
      return false;
    }
    return (parent.children || []).some((nodeItem) => {
      return nodeItem[this.valueField] === target[this.valueField] || this.isDescendant(nodeItem, target);
    });
  }
  private changeChildrenChecked(nodes: any[], checked) {
    if (!nodes) {
      return;
    }
    nodes.forEach((node) => {
      node.$check = checked;
      this.changeChildrenChecked(node.children, checked);
    });
  }
}
    <div class="node-item {{nodeCssClass}}" reDraggable="re:node-item-drop" [disabled]="!allowDraggable"
     [dragData]="{node: node, parent: parentNode}">
  <div class="node-item-panel">
    <i class="node-expend-icon {{getNodeExpendIcon()}}"
       (click)="onExpendedIconClick($event)"></i>
    <div class="node-item-content" #nodeItemContent reDroppable="re:node-item-drop" (onDrop)="onDropNodeItem($event)"
         (onDragEnter)="onDragEnter()" (onDragLeave)="onDragLeave()" [acceptDrop]="isAcceptDrop">
      <div class="node-check-box">
        <re-checkbox *ngIf="checkable" [(ngModel)]="node.$check" label=""
                     (valueChange)="nodeItemCheckedChange($event)"></re-checkbox>
      </div>
      <ng-container *ngIf="!nodeItemTemplate">
      <span class="node-text" [ngClass]="{'bg-primary': node.$select}" (click)="onNodeItemClick($event)"
            (dblclick)="onNodeItemDbClicked($event)">
        <i *ngIf="iconField && node[iconField]"
           class="node-icon {{node[iconField]}}"></i> {{node[textField] || ''}} <span
        class="loading" *ngIf="isLoading">
        <i class="{{loadingIcon}}"></i></span>
      </span>
        <div class="toolbar">
          <ng-template *ngIf="nodeItemToolbarTemplate" [ngTemplateOutlet]="nodeItemToolbarTemplate"
                       [ngTemplateOutletContext]="{$implicit: node, parentNode:parentNode, tree: this}"></ng-template>
        </div>
      </ng-container>
      <ng-container *ngIf="nodeItemTemplate">
        <ng-template *ngIf="nodeItemTemplate" [ngTemplateOutlet]="nodeItemTemplate"
                     [ngTemplateOutletContext]="{$implicit: node,  parentNode:parentNode, tree: this }"></ng-template>
      </ng-container>
    </div>
  </div>
  <re-tree-panel *ngIf="node.children && node.children.length && node.$expend"
                 class="children-view"
                 [treeData]="node.children"
                 [textField]="textField"
                 [valueField]="valueField"
                 [iconField]="iconField"
                 [checkable]="checkable"
                 [lazyLoad]="lazyLoad"
                 [loadingIcon]="loadingIcon"
                 [loadChildren]="loadChildren"
                 [allowDraggable]="allowDraggable"
                 [allowMutipleSelected]="allowMutipleSelected"
                 [parentNode]="node"
                 [nodeItemTemplate]="nodeItemTemplate"
                 [nodeItemToolbarTemplate]="nodeItemToolbarTemplate"
                 [leafIcon]="leafIcon"
                 [expendIcon]="expendIcon"
                 [collapseIcon]="collapseIcon"
                 (nodeItemCheckedChanged)="onChildrenNodeCheckedChange($event)"
  ></re-tree-panel>
</div>