无法更改当前节点的展开/折叠图标

时间:2019-03-13 16:40:23

标签: angular ng-class

我试图在树节点展开或折叠时更改我的树节点的图标。我可以成功更改图标,但是问题是树中所有图标都更改了。我只想更改我单击的节点的图标。 我的代码如下:

html文件

<div class="container sidenav-tree">
  <ng-template #recursiveList let-files>
    <div *ngFor="let item of files">
      <div class="row node-item">
        <i
          data-toggle="collapse"
          attr.data-target="#{{item.reference}}"
          class="fa"
          [ngClass]="{'fa-angle-down': isExpanded, 'fa-angle-right': !isExpanded}"
          *ngIf="!(item.children.length===0)"
          (click)="isExpanded=!isExpanded"></i>
        {{item.name}}
      </div>
      <div id="{{item.reference}}" class="container collapse" *ngIf="!(item.children.length===0)">
        <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }"></ng-container>
      </div>
    </div>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: files }"></ng-container>
</div>

和组件文件:

import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../../../services/blog.service';

@Component({
  selector: 'app-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.css'],
})
export class SidenavComponent implements OnInit {
  files: [];
  selectedFile: string;
  selectedPath: string;
  isExpanded = false;


  constructor(private blogService: BlogService) {
  }

  ngOnInit() {
    this.blogService
      .getTreeNodes()
      .subscribe((files: []) => {
        console.log(files);
        this.files = files;
      });
  }

  nodeSelectEvent(event) {
    this.blogService.selectedNode.next(event.target.innerText);
  }
}

我想在ts文件而不是组件文件中尽可能保留我的逻辑。请在我的代码中建议所需的更改。

2 个答案:

答案 0 :(得分:0)

您的布尔值isExpanded用于每个项目,因此,如果一个项目将值更改为true,则所有项目的状态都会更改。 您必须创建一个Map来存储每个项目状态,并使用它来确定节点是否展开。

我认为您可以在地图中使用item.reference键来标识每个项目。

类似的东西:

组件

import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../../../services/blog.service';

@Component({
  selector: 'app-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.css'],
})
export class SidenavComponent implements OnInit {
  files: [];
  selectedFile: string;
  selectedPath: string;
  isExpanded = false;
  public itemsState = new Map<string, boolean>();


  constructor(private blogService: BlogService) {
  }

  ngOnInit() {
    this.blogService
      .getTreeNodes()
      .subscribe((files: []) => {
        console.log(files);
        this.files = files;
        this.files.forEach(item => {
            // init all items to not expanded
            this.itemsState.set(item.reference, false);
        }
      });
  }

  nodeSelectEvent(event) {
    this.blogService.selectedNode.next(event.target.innerText);
  }
}

HTML:

<div class="container sidenav-tree">
  <ng-template #recursiveList let-files>
    <div *ngFor="let item of files">
      <div class="row node-item">
        <i
          data-toggle="collapse"
          attr.data-target="#{{item.reference}}"
          class="fa"
          [ngClass]="{'fa-angle-down': itemsState.get(item.reference), 'fa-angle-right': !itemsState.get(item.reference)}"
          *ngIf="!(item.children.length===0)"
          (click)="isExpanded=!isExpanded"></i>
        {{item.name}}
      </div>
      <div id="{{item.reference}}" class="container collapse" *ngIf="!(item.children.length===0)">
        <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }"></ng-container>
      </div>
    </div>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: files }"></ng-container>
</div>

该代码未经测试,仅用于解释原理

答案 1 :(得分:0)

由于这似乎是任意深度的递归树,所以最简单的方法是 声明一个对象以对您似乎要检索的文件列表进行建模,并在该实体上具有一个属性,该属性描述文件是否已扩展。

类似于添加到您的组件中的类

public export File{
  Name:string;
  isExanded:boolean;
}

然后我将您的文件数组更改为

files:File[]

在订阅中加载数据时,您可以更新服务以使用类似的DTO对象并返回该集合,也可以遍历获取的字符串列表并创建File对象实例。此时,您可以将isExanded选项初始化为false(除非您要持久保存状态服务器端)。

然后我将在树上实现一个事件处理程序,以更新当前文件的状态

toggleFileState(item:File){
  item.isExpanded = !item.isExpanded;
}

更新您的click事件以调用此事件处理程序并传递当前项目值。同时更新您的[ngClass]以引用当前项目对象实例上的isExpanded属性

[ngClass]="{'fa-angle-down':item.isExpanded, 'fa-angle-right':!item.isExpanded'}"