File

projects/rebirth-ng/src/lib/tree-view/tree-node.component.ts

Metadata

exportAs treeNode
selector re-tree-node,[reTreeNode]
styleUrls tee-node.component.scss
templateUrl ./tee-node.component.html

Index

Properties
Methods
Inputs

Constructor

constructor(treeViewComponent: TreeViewComponent, treePanelComponent: TreePanelComponent, renderer: Renderer2)
Parameters :
Name Type Optional
treeViewComponent TreeViewComponent no
treePanelComponent TreePanelComponent no
renderer Renderer2 no

Inputs

allowDraggable

Default value: false

allowMutipleSelected

Default value: false

checkable

Default value: false

collapseIcon
expendIcon
iconField

Type: string

lazyLoad

Default value: false

leafIcon
loadChildren

Type: function

loadingIcon

Type: string

node

Type: any

nodeCssClass

Type: string

nodeItemTemplate

Type: TemplateRef<any>

nodeItemToolbarTemplate

Type: TemplateRef<any>

parentNode

Type: any

textField

Type: string

valueField

Type: string

Methods

Private changeChildrenChecked
changeChildrenChecked(nodes: any[], checked: )
Parameters :
Name Type Optional
nodes any[] no
checked no
Returns : void
getNodeExpendIcon
getNodeExpendIcon()
Returns : any
Private isDescendant
isDescendant(parent: , target: )
Parameters :
Name Optional
parent no
target no
Returns : any
isLeaf
isLeaf()
Returns : boolean
Private isNodeMyself
isNodeMyself(dropData: any)
Parameters :
Name Type Optional
dropData any no
Returns : boolean
nodeItemCheckedChange
nodeItemCheckedChange(checked: )
Parameters :
Name Optional
checked no
Returns : void
onChildrenNodeCheckedChange
onChildrenNodeCheckedChange(node: )
Parameters :
Name Optional
node no
Returns : void
onDragEnter
onDragEnter()
Returns : void
onDragLeave
onDragLeave()
Returns : void
onDropNodeItem
onDropNodeItem($event: )
Parameters :
Name Optional
$event no
Returns : void
onExpendedIconClick
onExpendedIconClick($event: )
Parameters :
Name Optional
$event no
Returns : void
onNodeItemClick
onNodeItemClick($event: )
Parameters :
Name Optional
$event no
Returns : void
onNodeItemDbClicked
onNodeItemDbClicked($event: )
Parameters :
Name Optional
$event no
Returns : void

Properties

isAcceptDrop
isAcceptDrop:
Default value : ($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; }
isLoading
isLoading: boolean
Type : boolean
nodeItemContent
nodeItemContent: ElementRef
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>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""