【问题标题】:Event bubling using hostevent listener使用主机事件侦听器的事件冒泡
【发布时间】:2017-08-08 07:19:08
【问题描述】:

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

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

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

重现步骤:

  1. 添加多个子元素
  2. 点击 Escape 会关闭所有元素

预期行为:

  1. 当在最后添加的子元素上单击 Escape 键时需要触发事件

【问题讨论】:

  • 我不明白问题出在哪里...我按了退出,它们都关闭了,我按删除,相邻的关闭了?
  • 用户有两个选项可以通过单击删除按钮或转义来删除添加的子项。当我单击转义键时,您可以看到所有添加的子项都被删除。我只希望最近添加的元素是并非全部删除
  • 最近你的意思是添加的最后一个?
  • @zze 是的,最后添加了一个

标签: angular


【解决方案1】:

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

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

plnkr

我的应用

@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);
    }
}

【讨论】:

  • 谢谢@PierreDuc。上面的代码有一个小问题。当我点击转义键时,它实际上删除了第一个添加的元素而不是最后添加的元素。你们能告诉我我能做什么让它工作
  • 我已经更新了我的答案。我的错,我忘了补充说它应该删除数组的最后一个索引。我也会更新 plnkr
  • 谢谢它真的解决了我的问题。我很想知道是否可以从最后一个订阅的元素触发事件。我的意思是当我添加一个子元素时,指令订阅键盘转义键事件为什么不让最后添加的元素转义键事件首先触发并且那么剩下的呢?
  • 因为 CloseDirective 被创建了 3 次。您可以尝试在您从指令注册的位置创建一个service,并让它处理转义事件,并且只将其发送到最后一个注册的指令
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 2012-02-26
  • 2018-09-04
相关资源
最近更新 更多