元素包含不起作用(Angular 2+、RxJS)

TSR*_*TSR 6 dom rxjs typescript angular

这是我的代码。https://stackblitz.com/edit/angular-tq2vaa

constructor(private host: ElementRef) {
}

get element() {
    return this.host.nativeElement;
}

private editModeHandler() {
     const clickOutside$ = fromEvent(document, 'click').pipe(
        filter(({ target }) => {
        console.log('parent', this.element, 'child', target)

          const ans = this.element.contains(target) === false
          console.log(ans)
          return  ans
        }),
        take(1)
     )
}
Run Code Online (Sandbox Code Playgroud)

这是它在控制台中打印的内容。正如你所看到的,app-editable-component 包含 h3,它是目标,但为什么 ans 是 true???

续

bub*_*les 3

我尝试测试你的代码,请参阅此处

import { Component, ElementRef } from '@angular/core';
import  {fromEvent } from 'rxjs';
import { filter, take } from 'rxjs/operators';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

constructor(private host: ElementRef) {
  this.editModeHandler();
}

get element() {
    return this.host.nativeElement;
}

private editModeHandler() {
      fromEvent(document, 'click')
      .pipe(
        filter(({ target }) => {
        console.log('parent', this.element, 'child', target)

          const ans = this.element.contains(target) === false
          console.log(ans)
          return  ans
        }),
        take(1)
     ).subscribe();
}  

}
Run Code Online (Sandbox Code Playgroud)

当我点击<h3>标签ans时显示false!我和你做同样的事情吗?我错过了什么吗?

在此输入图像描述

更新

在你的 stackblitz 之后我明白发生了什么。我会尽量简单一些:

  1. 您点击该h3元素
  2. edit模式已激活(因此h3被 替换input
  3. 点击事件被捕获,document因为点击正在冒泡,并且contains(h3)将返回false(因为#2)
  4. switchMapTo(clickOutside$)被执行
  5. view模式已激活(速度非常快,因此您不会看到输入出现和消失)。

要修复此问题,您可以在传播被宿主元素捕获时停止传播。

private viewModeHandler() {
        fromEvent(this.element, 'click').pipe(
            untilDestroyed(this)
        ).subscribe((e) => {
            console.log('clicked inside');
            this.editMode.next(true);
            this.mode = 'edit';
            e.stopPropagation();
        });
    }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。