我试图在树节点展开或折叠时更改我的树节点的图标。我可以成功更改图标,但是问题是树中所有图标都更改了。我只想更改我单击的节点的图标。 我的代码如下:
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文件而不是组件文件中尽可能保留我的逻辑。请在我的代码中建议所需的更改。
答案 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'}"