无法更改当前节点 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'}"
我试图在展开或折叠树节点时更改树节点的图标。我能够成功地更改图标,但问题是树中的所有图标都发生了变化。我只想更改我单击的节点的图标。 我的代码如下:
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'}"