angular - Angular 指令多次调用
问题描述
树视图.html
<div *ngFor="let item of nodes; let i=index" class="parent" [id]="item.name" appTreeView>
{{item.name}}
<div class="child" *ngIf="item.child">
<app-tree-view [nodes]="item.child"></app-tree-view> // recursive call
</div>
</div>
树视图.ts
this.data=[
{
name:"level 1",
child:[
{
name:"level 1.1",
}
]
},
{
name:"level 2",
child:[
{
name:"level 2.1",
child:[
{
name:"level 2.1.1"
}
]
}
]
}
]
指令.ts
import { Directive, HostListener,Renderer2 } from '@angular/core';
@Directive({
selector: '[appTreeView]',
})
export class TreeViewDirective {
constructor(private render:Renderer2) { }
@HostListener('click',['$event'])
check(event){
console.log(event.target.id);
const avalclass:string=event.target.classList.value;
if(avalclass.includes('expand')){
this.render.removeClass(event.target,'expand');
}else{
this.render.addClass(event.target,'expand');
}
}
}
输出
- 1级
- 2级
如果我单击 2 级展开子菜单 2.1 级 控制台打印一次
- 1级
- 2级
- 2.1级
然后我点击 2.1 级展开子菜单 2.1.1 控制台打印两次
- 1级
- 2级
- 2.1级
- 2.1.1 级
- 2.1级
为什么控制台打印多次。我的错误是什么
解决方案
控制台打印多次相同,因为您使用递归来调用 parent 及其后代。您将多次绑定单击事件,具体取决于您单击的元素的级别。如果您知道代码的流程:
- 如果单击第一个级别项目(级别 1 或级别 2):它会打印一次。
- 如果单击第二级项目(1.1 级或 2.2 级):它会打印两次,一次用于第二级,另一次用于第一级。
- 等等..
我已经准备了一个演示,其中包含您在问题中输入的代码。您可以在控制台中看到谁在调用事件以及谁是每次的主机元素。
https://stackblitz.com/edit/angular-recursion-directives?file=src/app/tree-view.directive.ts
您可以解决在指令中添加标志并在检查函数中检查它的问题:
if (this.isFired) {
return;
}
this.isFired = true;
或者比较当前宿主元素和触发事件的元素:
if(this.el.nativeElement.id == event.target.id){
console.log("click on: " + event.target.id);
const avalclass: string = event.target.classList.value;
if (avalclass.includes("expand")) {
this.render.removeClass(event.target, "expand");
} else {
this.render.addClass(event.target, "expand");
}
}
}
推荐阅读
- android - Android scoped storage and persistent files
- excel - Custom Menu in Excel toolbar using VBA
- python - Tkinter Button Align with Grid
- ios - Share extension not working properly with ios 13
- javascript - Javascript:在类构造函数之前调用 IIfe
- php - Recieving a 405 error, Method not allowed, when using a form to get data from the client
- asp.net - Single session between Chrome extension and Web pages possible?
- c++ - 垃圾收集在内存中移动引用的对象会破坏 Unreal4 引擎中的引用?
- html - CSS3 转换属性不适用于响应式导航栏
- python - 用 Python 求解联立方程