无法更改当前节点 expand/collapse 上的图标

Not able to change icon on expand/collapse for current node

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

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文件而不是component文件中。请建议我的代码中所需的更改。

您的布尔值 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>

代码未测试,只是说明原理

因为这似乎是一个任意深度的递归树,最简单的事情是 声明一个对象来模拟您似乎正在检索的文件列表,并在该实体上有一个描述它是否被扩展的属性。

类似 class 的内容已添加到您的组件中

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

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

files:File[]

当您在订阅中加载数据时,您可以更新您的服务以使用类似的 DTO 对象和 return 该集合,或者您可以遍历您获得的字符串列表并创建 File 对象实例。这时你可以将 isExanded 选项初始化为 false(除非你想在服务器端保持状态)。

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

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

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

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