使用主机事件侦听器的事件冒泡



我构建了一个指令,该指令使用主机事件侦听器订阅键盘事件。当按下转义键时,我正在触发这样的输出事件

@HostListener('document:keyup', ['$event'])
handleKeyboardEvent(kbdEvent: KeyboardEvent) {
if (kbdEvent.keyCode === 27) {
this.CloseEvent.emit();
}
}

我对子元素有这个指令。按下转义键时,我只想为新订阅的元素触发输出事件。问题是当我单击转义键时,事件会根据分层顺序触发。我在这里做了一个演示:https://plnkr.co/edit/FfnHAtxl2zcHsu0JilKt

重现步骤:

  1. 添加多个子元素
  2. 点击转义它关闭所有元素

预期行为:

  1. 单击Esic键时,需要触发最后添加的子元素事件

一种方法是发送KeyboardEventclose事件。然后,您可以检查事件是否已defaultPrevented设置为 true,如果没有,则执行删除并preventDefault

我做了一些优化。您可以只使用'document:keyup.ESC'绑定,您可以立即设置(close)它将使用CloseDirective

普罗提

我的应用

@Component({
selector: 'my-app',
template: `
<h4>Add Multiple Child And Click On Escape key</h4><br>
<div *ngFor="let child of childArray;let i = index">
<div style="display:flex;flex-direction:row">
<my-chid (close)="onClose($event)" [index]="child"></my-chid>
<button (click)="deleteChild(i)">Delete</button>
</div>
</div>
<button (click)="addChild()">Add Child</button>
`,
})
export class App {
childArray: any[] = [];
addChild(): void {
this.childArray.push(this.childArray.length);
}
onClose(event: KeyboardEvent): void {
if (!event.defaultPrevented) {
event.preventDefault();
this.deleteChild(this.childArray.length - 1);
}
}
deleteChild(index: number): void {
this.childArray.splice(index, 1);
}
}

我的孩子

@Component({
selector: 'my-chid',
template: `
<div>
I am child {{index}}
</div>
`,
})
export class MyChild {
@Input()
public index: number; 
}

关闭指令

@Directive({
selector: '[close]'
})
export class CloseDirective {
@Output() close: EventEmitter<KeyboardEvent> = new EventEmitter<KeyboardEvent>();
@HostListener('document:keyup.ESC', ['$event'])
handleKeyboardEvent(kbdEvent: KeyboardEvent) {
this.close.emit(kbdEvent);
}
}