【问题标题】:How to prevent propagation of events from a specific component in Angular?如何防止来自Angular中特定组件的事件传播?
【发布时间】:2019-10-14 05:15:29
【问题描述】:

TLDR:

有没有办法确保特定组件触发的事件不会传播到该组件之外?

或者,稍微不那么可取:有没有办法使给定Directive 中定义的@HostListener 注入组件中,以忽略另一个特定同级组件触发的事件?

澄清背景

假设我有一个如下所示的页面:

父组件 (1) 包括行列表(子组件 (3))和顶部的表单(另一个子组件 (2))。该表单包含一个输入字段。

我打算允许用户在按下jk 时通过键盘导航列表,这会稍微改变其中一行的背景颜色。我通过在组件 (3) 中引入 Directive 来实现这一点,该组件使用 HostListener 来监听 jk 的按下事件。

  @HostListener('document:keydown', ['$event'])
  onKeydown(event: KeyboardEvent) {
    // pressing keys 'i' and 'j' should navigate through list of suites
    if (['j', 'k'].includes(event.key)) {
      this.navigate(event.key);
    }
  }

这种方法的问题在于,即使在组件 3 中注入此指令,它似乎也会在整个页面中捕获 any 按下事件 jk,包括用户输入时组件 2 中表单的输入字段中的文本,恰好包含字符 jk

为了避免这种情况,我希望指令足够智能以忽略组件 2 触发的事件,或者确保组件 2 的事件永远不会传播到外部。

【问题讨论】:

    标签: angular


    【解决方案1】:

    在了解有关 DOM 事件传播的更多信息后,我可能通过为组件 2(表单)注册一个单独的 HostListener 来解决我的问题,该组件捕获特定的 pressdown 事件并阻止它们传播到父级或其他文档中的组件,使用Event.stopImmediatePropagation:

      @HostListener('keydown', ['$event'])
      onKeydown(event: KeyboardEvent) {
        if (['j', 'k'].includes(event.key)) {
          event.stopImmediatePropagation();
        }
      }
    

    这可能足够通用,可以包装成一个单独的指令,用于可能触发不需要的事件的各种元素。但不确定这是否是一个好习惯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-11
      • 2020-09-09
      • 2020-01-26
      • 2018-07-26
      • 2021-07-10
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      相关资源
      最近更新 更多