【问题标题】:Advanced Angular @HostListener - Logging clicks for all elements within parent component (from child)Advanced Angular @HostListener - 记录父组件中所有元素的点击(来自子组件)
【发布时间】:2019-05-24 20:17:35
【问题描述】:

我想在其中保留子组件的逻辑。然而,事件本身是从其父组件向下发生单击时发生的。

child.component.ts

@HostListener('document:click', ['$event']) onClick(event: MouseEvent) {

  // get the parent component tag
  const parentComponent = this.eRef.nativeElement.parentNode.parentNode;

  for (let i = 0, j = parentComponent.length; i < j; i++) {
    if (event.target == parentComponent[i]) {
        console.log(parentComponent[i]);
    }
  }

我尝试了很多方法来遍历节点列表并比较 click event.target 以查看点击是在 parent 内部还是外部,但我似乎无法迭代 nodeList 并且不明白为什么.

我在 repro StackBlitz 上也尝试了许多其他方法。

也许有更好的方法来监视该组件的父级外部/内部的点击?另外,我不想将点击逻辑移动到父级,除非必须,否则逻辑不属于那里。

已修复:StackBlitz 已更新,其中包含我对使用 elementRef 遍历 DOM 的所有研究。 @Ritchie 也正确地遍历了 nodeList 并让它以这种方式工作。

【问题讨论】:

  • 为什么不能把@HostListener 放在父级上,然后通过@Input 将流传递给子级?处理逻辑可以留在子级中。

标签: javascript angular events event-handling


【解决方案1】:

您可以使用MouseEventtarget 属性来检查单击了哪个组件并将其与父节点名称进行比较。

@HostListener('document:click', ['$event.target']) onClick(event) {
    const parentEl = this.eRef.nativeElement.parentNode.tagName;

    const path = [];
    let currentElem = event;
    while (currentElem) {
      path.push(currentElem.tagName);
      currentElem = currentElem.parentElement;
    }
    console.log('Clicked inside parent: ', path.includes(parentEl));
}

Stackblitz Example

【讨论】:

  • 关闭!但这只是在他们实际单击特定父组件的情况下。父级中的任何元素呢? (包括此子组件中的元素)这就是为什么我抓住父节点并尝试循环比较每个元素与单击的元素。
  • 对不起,我误解了你的问题。我已经更新了我的答案。我添加了一个循环来遍历所有父元素并检查它是否包含指定的元素。
  • 好的,所以我在 stackblitz 中设置了您的解决方案。它也无法像您预期的那样循环。
  • 我已经分叉了您的 Stackblitz 示例,并且该行为似乎按照您的描述工作:stackblitz.com/edit/hostlistener-dom-traveral-js61mb?file=src/…您能告诉我什么工作不正常吗?
猜你喜欢
  • 1970-01-01
  • 2020-03-29
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
相关资源
最近更新 更多