首页 > 解决方案 > 从 Angular 6 材质树中的子节点获取父层次结构

问题描述

我正在按照教程在 Angular 6 中实现 cdk 树。我创建了一个树结构,现在我想通过使其可点击来从子级获取父层次结构,而有诸如 getDescendants 之类的方法来获取节点的子级,副反之亦然。如何从子节点或叶节点获取父层次结构。

标签: angulartypescriptangular-materialangular6angular-cdk

解决方案


我已将这些方法添加到我的树组件中。请注意,我使用的是扁平树,这不适用于嵌套树。

@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;
      }
    }
  }
}

我计划创建自己的FlatTreeControl(通过扩展 Angular CDK's FlatTreeControl)并将这个逻辑移到那里。

更新

我已将上述逻辑移至我自己的FlatTreeControl实现中:

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;
      }
    }
  }
}

推荐阅读