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

问题描述 投票:0回答:2

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

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

angular ng-class
2个回答
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'}"

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>

代码未经过测试,只是为了解释原理

© www.soinside.com 2019 - 2024. All rights reserved.