Element contains not working (Angular 2+, RxJS)

Viewed 1506

Here is my code. 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)
     )
}

This is what it prints in the console. As you can see, app-editable-component contains h3 which is the target but why ans is true???

cont

1 Answers

I tried to test your code, see here

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();
}  

}

when i click on the <h3> tag ans shows false ! am i doing the same thing as you ? am i missing something ?

enter image description here

UPDATE .

After your stackblitz i see what's happening. I'll try to be simple :

  1. You click on the h3 element
  2. edit mode is activated (so the h3 is replaced by the input)
  3. The click event is catched by the document because click is bubbling and the contains(h3) will return false (because of #2)
  4. switchMapTo(clickOutside$) is executed
  5. view mode is activated (really speed, so you'll not see the input appearing ans disappearing).

To fix it, you can stop the propagation when its catched by the host element.

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

Hope this helps.

Related