【问题标题】:Angular Material Flat Tree Parent Children Graphical Representaion角材料平面树父子图形表示
【发布时间】:2020-01-30 17:52:45
【问题描述】:

我想在 Angular Material Flat Tree 上显示父子图形表示。

这是设计:

这是我目前所做的DEMO

【问题讨论】:

标签: angular filetree angular-tree-component


【解决方案1】:

第一个解决方案

这里是stackBlitz Demo

这里是stackBlitz editable link

我已经使用treeControl.dataNodes.indexOf(node)对每个可见节点进行了递归调用,以引用节点索引

这里是递归函数:

  recNode(arr:any[], data:any[], index:number, maxIndex:number):any[]{
    if (arr === undefined)
      arr = [];
    for (let i = 0; i < data.length; i++){
          index++
          if (index === maxIndex)
            return ([true, index, arr]);
          if (data[i].children.length){
            let res = this.recNode(arr, data[i].children, index, maxIndex)
            index = res[1];
            if (res[0] === true)
            {
              arr.splice(0, 0, (i !== (data.length - 1)))         
              return ([true, index, arr]);
            }
        }
    }
    return ([false, index, arr]);
  }

这将为您的 [ngClass] 返回一个 true false 值数组

然后在 html 中我调用该函数

<li *ngFor="let r of recNode(undefined, dataSource.data, -1, treeControl.dataNodes.indexOf(node))[2]; [ngClass]="{'node-arrow': r, 'node-arrow-empty': !r}" ></li>

最后我在 CSS 中创建了另一个名为 node-arrow-empty 的无边框类

   .node-arrow-nox {
      position: relative;
      // min-width: 48px;
      // min-height: 48px;
      .node-arrow {
        position: relative;
        min-width: 48px;
        min-height: 48px;
        &:before {
          content: "";
          position: absolute;
          top: -20px;
          left: 20px;
          border-left: 1px solid $copounsCount;
          bottom: 0;
        }
      }
      .node-arrow-empty {
        position: relative;
        min-width: 48px;
        min-height: 48px;
        &:before {
          content: "";
          position: absolute;
          top: -20px;
          left: 20px;
          bottom: 0;
        }
      }
    }

根据数组中的值是true 还是false,它会在两个类之间切换html。

第二个解决方案

stackBlitz DEMO

stackBlitz editable link

另一种解决方案是通过添加例如isLast:boolean 属性来跟踪数组中的最后一个元素。当然,如果您处理的数据是动态的,您需要找到一种方法来动态更改该值。

一旦isLast 被填满,您将进行递归调用,它将找到current node level - 1 的前一个兄弟。话虽如此,您将检查两件事。首先是节点类包含n-last(这是我给Html 的类名,代表父数组的最后一个元素),第二件事是检索类n-{{node-level}}

通过递归(如果您不想这样做,您可以使用非递归方法)检索具有类 n-3n-2previousElementSibling ... 到 n-0 您可以检查每个元素是否包含一个n-last 类。您将truefalse 推入一个数组,就像第一个解决方案在node-arrownode-arrow-empty 之间切换一样。

这里是递归函数

  dummy(el:any, arr:any[], level:number){
    let classes = el.className;
    if (arr === undefined)
     arr = [];
    else{
     arr.splice(0, 0, classes.includes('n-last'));
    }
    let np = /(?!n-)\d+/g;
    let m = classes.match(np);
    let nLevel = parseInt(m[0]);
    nLevel--
    if (nLevel < 0)
      return (arr)
    while (parseInt(el.className.match(np)[0]) !== nLevel){
      el = el.previousElementSibling
    }
    arr = this.dummy(el, arr, nLevel)
    return (arr)
  }

HTML(这里只是父节点,子节点相同)

<mat-tree-node #refP   class="parent-node {{'n-' + node.level}} " *matTreeNodeDef="let node; when: grpNode;" matTreeNodePadding matTreeNodePaddingIndent="0" cdkDrag [cdkDragData]="node" [ngClass]="{'no-child': !node.children.length, 'n-last': node.isLast}">
  <span class="node-arrow-nox d-flex">
    <li [ngClass]="{'node-arrow': !r , 'node-arrow-empty': r}" *ngFor="let r of dummy(refP, undefined, node.level)"></li>
  </span>
  <button class="node-toggle" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.filename" [disabled]="!node.children.length">
    <mat-icon class="mat-icon-rtl-mirror toggle-arrow">
      {{treeControl.isExpanded(node) ? 'play_arrow' : 'play_arrow'}}
    </mat-icon>
  </button>
  <div class="node-icon icon-h-arw"></div>
  <div class="node-name">{{node.isLast}}-{{node.accntCode}} <span>: :</span> {{node.name}} </div>
</mat-tree-node>

如您所见,我正在使用名为 #refP 的模板变量将元素传递给虚拟函数

这里是 PARENTNODECHILDNODE 声明:

export class PARENTNODE {
  id: string;
  isLast: boolean;
  ...
  actAsSupplier: boolean;
}

/* Flat node with expandable and level information */
export class CHILDNODE {
  constructor(
    public id: string,
    public isLast: boolean,
    ...
    public actAsSupplier: boolean,
  ){}
}

第三种解决方案

我不会编写代码,但我会尝试解释它。

这有点类似于以前的解决方案,除了您可以在更改树时解析(交换、删除、添加)数据并添加像 divType 这样填充有 truefalse 的属性并调用它你的html就是这样

 <li *ngFor="let r of node.divType" [ngClass]="{'node-arrow': r, 'node-arrow-empty': !r}" ></li>

【讨论】:

    猜你喜欢
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多