Angular 4+ Detect点击Div或嵌套的子Div,并区别于其他外部Div

时间:2018-02-14 18:51:37

标签: angular elementref

我看过许多Angular 2页面循环遍历nativeElements的层次结构。它们不适用于Angular 4,5,...... 我需要向“工作区”DIV添加一个指令。将有其他Div作为工作空间的父级,其他Div是嵌套到任何级别的子DIV。 该指令必须检测鼠标单击“workspace”div或任何嵌套div,我必须确定它实际上是一个嵌套子项或工作区 - 而不是工作区或工作区外的其他div。

这源自网络上的众多例子之一:

    import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[shMonitorInfoClicks]'
})
export class MonitorInfoClicksDirective {
  public elementRef;

  constructor(private myElement: ElementRef) {
    this.elementRef = myElement;
  }

  @HostListener('document:click', ['$event'])
  public onClick(event: Event): void {
    let clickedComponent = event.target;
    let inside = false;
    do {
      if (clickedComponent === this.elementRef.nativeElement) {
        inside = true;
        break;
      } else {
        clickedComponent = clickedComponent.parentNode;  <<<<====== see below
      }
    } while (clickedComponent);
    if(inside) {
      console.log('inside');
    } else {
      console.log('outside');
    }
  }
}

测试HTML:

<div>
  This is outside the workspace
</div>
<div shMonitorInfoClicks  [ngStyle]="{'height': '200px', 'width': '300px', 'border': '1px solid red'}">
  This is the workspace
  <div [ngStyle]="{'height': '100px', 'width': '100px', 'border': '1px solid green'}">
    A workspace child
  </div>
</div>

当我暂停Chrome调试器时,我可以使用控制台使parentNode或parentElement工作。但是,我无法通过Typescript / Angular CLI。我确定我正在运行@latest Angular。 (这是5)。

任何帮助将不胜感激。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

event.target.parentNode引用没有通过编译器,因为编译器正在查看event.target EventTarget,而parentNode没有event.target属性。为了告知编译器您的event.target到底是什么,您需要use a type assertion来投射HTMLElement它的真实类型,在您的情况下是{{1} }:

const target = event.target as HTMLElement;

现在您可以访问target.parentNode

您能够在控制台中看到它的原因是因为它在运行时打印出event.target(未包含的类型),但是Angular的事件对象{{1} } property返回其他内容。您可以在此处看到 little 更多信息:https://angular.io/guide/user-input#type-the-event,但很难找到更多相关信息。

无论如何,您总是可以使用控制台找出target的真实类型,然后在代码中将event.target转换为该类型。然后你可以访问你在控制台中看到的所有那些属性,而不需要编译器投入使用:)