树材料角度2选择状态

时间:2018-05-31 20:49:35

标签: angular typescript angular-material

当我从树中单击一个节点时,我有一个Angular 2 Material Tree我需要在该节点上选择状态来更改背景颜色。 我不知道我怎么能这样做。我没有在文档中找到任何帮助我的内容。这是html代码和它应该如何看待树的图片

That is how it should look the tree when clicking on a node

       <mat-tree [dataSource]="dataSource" [treeControl]="treeControl" #matTree [ngStyle]="{ 'color': red}">
        <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding>
          <button mat-icon-button disabled></button>
          {{node.filename}}
        </mat-tree-node>

        <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding >
          <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.filename" click="onClick()">
            <mat-icon class="mat-icon-rtl-mirror">
              {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
            </mat-icon>
          </button>
          {{node.filename}}
        </mat-tree-node>
      </mat-tree>

2 个答案:

答案 0 :(得分:5)

我设法开发了一个你想要实现的实例。演示文稿是基本的,但它使用与示例代码相同的布局。我在解决方案的最底部添加了一个链接。它基本上归结为以下代码。

component.ts

  // inside of the component class

  @ViewChildren(MatTreeNode, { read: ElementRef }) treeNodes: ElementRef[];

  hasListener: any[] = [];
  oldHighlight: ElementRef;

  updateHighlight = (newHighlight: ElementRef) => {
    this.oldHighlight && this.renderer.removeClass(this.oldHighlight.nativeElement, 'background-highlight');

    this.renderer.addClass(newHighlight.nativeElement, 'background-highlight');
    this.oldHighlight = newHighlight;
  }

  ngAfterViewChecked() {
    this.treeNodes.forEach((reference) => {
      if (!this.hasListener.includes(reference.nativeElement)) {
        console.log('* tick');

        this.renderer.listen(reference.nativeElement, 'click', () => {
          this.updateHighlight(reference);
        });
        this.renderer.listen(reference.nativeElement.children.item(0), 'click', () => {
          this.updateHighlight(reference);
        });

        this.hasListener = this.hasListener.concat([ reference.nativeElement ]);
      }
    });

    this.hasListener = this.hasListener.filter((element) => document.contains(element));
    console.log('*', this.hasListener.length);
  }

component.css

.background-highlight {
  background-color: whitesmoke;
}

我将大部分逻辑放在ngAfterViewInit生命周期钩子中。这样我就可以访问@ViewChild查询的结果了。该查询返回对模板中所有<mat-tree-node></mat-tree-node>元素的引用。结果存储在this.treeNodes中作为QueryList。

我遍历列表。我检查引用的nativeElement是否已经有它的事件监听器。事件侦听器在鼠标click上触发。回调updateHighlight处理background-highlight css类的删除和添加,以便它在DOM中保持唯一。

我添加了两个针对<mat-tree-node></mat-tree-node>及其嵌套<button></button>元素的事件侦听器。单击这两个位置将突出显示树节点。

updateHighlight中,我从之前添加的background-highlight类中删除了(如果适用)。无论当前点击什么,都会获得background-highlight课程。对单击元素的引用将替换先前的this.oldHighlight值。

为了表现,我加入了this.hasListener。该数组存储已收到其侦听器的<mat-tree-node></mat-tree-node>元素。我可以检查数组,以确保每次ngAfterViewChecked的传递都不会不必要地覆盖侦听器。

最后一点逻辑使this.hasListener不再失控。任何不再附加到DOM的元素都不再是一个问题。

我保留了两个console.log语句,因为它们的输出反映了代码的工作原理,而不是突出显示单击的树节点。

如有任何其他问题,请参阅存储库:https://github.com/sosmaniac-FCC/mat-tree-node-example/tree/master/src/app/components/example-one。我确实从@angular/core导入了一些额外的实用程序。

当然,如果我在任何地方错过了标记,请告诉我。我将尽我所能跟进。

答案 1 :(得分:5)

有一种更简单,更干净的方法来实现这一目标。

您要做的就是添加
var result = [{ "_id": "12345", "_type": "feeds", "_source": { "title": "hi all solve it", "link": "www.face.com", "content": "Hi thewwewewedwe asdasdasdasd", "createdAt": "2018-08-08T11:42:40.073Z", "updatedAt": "2018-08-08T11:42:40.073Z", "reply": [] } }, { "_id": "1234567", "_type": "feeds123", "_source": { "title": "hi all solve it 123", "link": "www.face.com", "content": "Hi thewwewewedwe asdasdasdasd", "createdAt": "2018-08-08T11:42:40.073Z", "updatedAt": "2018-08-08T11:42:40.073Z", "reply": [] } }]; var newArray = []; result.forEach(function(obj){ var tempObj = {}; Object.keys(obj).forEach(function(key){ if(key !== '_source'){ tempObj[key] = obj[key]; } else { tempObj = Object.assign(tempObj, obj[key]); } }); newArray.push(tempObj); }); console.log(newArray);
每个(click)="activeNode = node" [ngClass]="{ 'background-highlight': activeNode === node }"

不要忘记将mat-tree-node变量添加到您的组件中。

就是这样!