在Angular 2中使用影子DOM时,Node.contains()是否起作用?

Mar*_*rgh 4 shadow-dom angular

我在文档中的任何地方都找不到它,但是当我单击作为父组件一部分的组件中的某个东西时,Node.contains()函数不起作用。

我的父组件如下所示:

<div class="body">
    <div class="item" *ngFor="let item of sortedItems;">
        <cv-checkbox></cv-checkbox>
        <cv-svg-icon></cv-svg-icon>
    </div>

    <div class="drop-zones" *ngFor="let zone of sortedItems.length + 1 | numberToArrayPipe;>
        <div class="drop-zone"></div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

如您所见,我的父组件中有两个Angular组件:cv-checkboxcv-svg-icon。我向我的父组件添加了一个指令,如下所示:

<cv-layer-manager cvClickOutside (clickOutside)="toggleLayerManager()"></cv-layer-manager>
Run Code Online (Sandbox Code Playgroud)

我在哪里检查单击的节点是否包含在父级中,如下所示:

@HostListener('document:click', ['$event']) public onClick(event: MouseEvent) {
    const clickedInside = this._elementRef.nativeElement.contains(event.target);
    if (!clickedInside) {
        this.clickOutside.emit();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我单击普通的HTML组件,那么一切都会按预期运行,但是当我单击Angular组件时,则不能正常运行。包含不检查Angular组件内部是否正确?

Mic*_*mpl 5

我在日期选择器中遇到了类似的问题。为了解决这个问题,我向当前组件添加了allowClose属性。

@ViewChild('element') elementRef: ElementRef;
private allowClose = true;
Run Code Online (Sandbox Code Playgroud)

然后,我添加了另一个HostListener,它仅侦听当前组件的事件。

@HostListener('click', ['$event'])
clickInside(event: any) {
  this.allowClose = false;
}
Run Code Online (Sandbox Code Playgroud)

然后,我修改了clickOutside方法以仅在allowClose为true时处理关闭,然后再次将allowClose设置为true。

@HostListener('document:click', ['$event'])
clickOutside(event: any) {
  if (!this.elementRef.nativeElement.contains(event.target) && this.allowClose) {
    this.handleClose();
  }
  this.allowClose = true;
}
Run Code Online (Sandbox Code Playgroud)

而已!


小智 4

请检查您是否像 ngIf 或 ngSwitch 一样刷新,以便子组件消失。因此,当您执行 ParentComponent.contains(childComponent) 时,尽管在您实际单击时存在,但它不会工作。我昨天观察到了这一点,而此代码不会工作,我必须部分使用这个来解决问题。谢谢。

  • 这是正确、简单的答案。- `.contains()` 不适用于具有 `*ngIf` 或 `*ngSwitch` 的元素 - 最简单的解决方案是使用 `[hidden]='myVar'` 绑定,这将像 AngularJs 中的 ng-hide 一样工作,不是从 DOM 中删除元素,只是使其不可见。有关“[hidden]='myVar'”的更多信息:/sf/answers/2490466541/ (3认同)