Get parent hierarchy from a child node in angular 6 material tree

后端 未结 3 1166
天涯浪人
天涯浪人 2021-02-15 12:06

I am following a tutorial to implement cdk tree in angular 6. I created a tree structure, now I want to get the parent hierarchy from from the child by making it clickable, whil

相关标签:
3条回答
  • 2021-02-15 12:37

    Thanks to Flauwekeul, a little bit simplified

    import { FlatTreeControl } from '@angular/cdk/tree';
    
    export class CustomTreeControl<T> extends FlatTreeControl<T> {
      /**
       * Iterate over each node in reverse order and expand each inferior level nodes until level 0.
       */
      expandParents(node: any) {
          const currentLevel = this.getLevel(node);
    
          if (currentLevel < 1) {
              return null;
          }
    
          const startIndex = this.dataNodes.indexOf(node) - 1;
    
          for (let i = startIndex; i >= 0; i--) {
              const currentNode = this.dataNodes[i];
    
              if (this.getLevel(currentNode) < currentLevel) {
                  this.expand(currentNode);
                  if (this.getLevel(currentNode) === 0) break;
              }
          }
      }
    }
    
    0 讨论(0)
  • 2021-02-15 12:40

    Parent hierarchy can be stored in Array of numbers where each number is index of reccurent nested node. In order to expand tree on specified node I tried use previous examples, but eventually I decided make it that way:

    1) ChangePath must be call every time we click on node:

    changePath(node) {
    if (node.level < this.nodePath.length) {
      this.nodePath.splice(node.level, this.nodePath.length - node.level);
    }
    this.nodePath.push(this.treeControl.dataNodes.indexOf(node));}
    

    2) Next, when tree collapses, we must call expand of every item in nodePath (when tree collapse in is caused by delete node we dont want expand it, so last element is removed from path):

    expandTreeOnSpecifiedNode(isDelete: boolean) {
      if (isDelete) {
        this.nodePath.pop();
      }
      this.nodePath.forEach(id => {
        console.log(id);
        this.treeControl.expand(this.treeControl.dataNodes[id]);
        });
      }
    
    0 讨论(0)
  • 2021-02-15 12:49

    I've added these methods to my tree component. Note that I use the flat tree, this won't work for a nested tree.

    @Component({
      selector: 'es-outline-tree',
      // ...
    })
    export class OutlineTreeComponent implements OnInit {
      treeControl: FlatTreeControl<FlatTreeNode>;
    
      // other code...
    
      /**
       * Recursively expand all parents of the passed node.
       */
      expandParents(node: FlatTreeNode) {
        const parent = this.getParent(node);
        this.treeControl.expand(parent);
    
        if (parent && parent.level > 0) {
          this.expandParents(parent);
        }
      }
    
      /**
       * Iterate over each node in reverse order and return the first node that has a lower level than the passed node.
       */
      getParent(node: FlatTreeNode) {
        const { treeControl } = this;
        const currentLevel = treeControl.getLevel(node);
    
        if (currentLevel < 1) {
          return null;
        }
    
        const startIndex = treeControl.dataNodes.indexOf(node) - 1;
    
        for (let i = startIndex; i >= 0; i--) {
          const currentNode = treeControl.dataNodes[i];
    
          if (treeControl.getLevel(currentNode) < currentLevel) {
            return currentNode;
          }
        }
      }
    }
    

    I'm planning to create my own FlatTreeControl (by extending Angular CDK's FlatTreeControl) and move this logic there.

    UPDATE

    I've moved the above logic to my own FlatTreeControl implementation:

    import { FlatTreeControl } from '@angular/cdk/tree';
    
    export class CustomTreeControl<T> extends FlatTreeControl<T> {
      /**
       * Recursively expand all parents of the passed node.
       */
      expandParents(node: T) {
        const parent = this.getParent(node);
        this.expand(parent);
    
        if (parent && this.getLevel(parent) > 0) {
          this.expandParents(parent);
        }
      }
    
      /**
       * Iterate over each node in reverse order and return the first node that has a lower level than the passed node.
       */
      getParent(node: T) {
        const currentLevel = this.getLevel(node);
    
        if (currentLevel < 1) {
          return null;
        }
    
        const startIndex = this.dataNodes.indexOf(node) - 1;
    
        for (let i = startIndex; i >= 0; i--) {
          const currentNode = this.dataNodes[i];
    
          if (this.getLevel(currentNode) < currentLevel) {
            return currentNode;
          }
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题