web-dev-qa-db-ja.com

Angularコンポーネントの外側のクリックを検出

クリックを検出するにはどうすればよいですか?外部 Angularのコンポーネントですか?

58
AMagyar
import { Component, ElementRef, HostListener, Input } from '@angular/core';

@Component({
  selector: 'selector',
  template: `
    <div>
      {{text}}
    </div>
  `
})
export class AnotherComponent {
  public text: String;

  @HostListener('document:click', ['$event'])
  clickout(event) {
    if(this.eRef.nativeElement.contains(event.target)) {
      this.text = "clicked inside";
    } else {
      this.text = "clicked outside";
    }
  }

  constructor(private eRef: ElementRef) {
    this.text = 'no clicks yet';
  }
}

実際の例-ここをクリック

111
AMagyar

AMagyarの答えに代わるもの。このバージョンは、ngIfを使用してDOMから削除される要素をクリックすると機能します。

http://plnkr.co/edit/4mrn4GjM95uvSbQtxrAS?p=preview

  private wasInside = false;
  
  @HostListener('click')
  clickInside() {
    this.text = "clicked inside";
    this.wasInside = true;
  }
  
  @HostListener('document:click')
  clickout() {
    if (!this.wasInside) {
      this.text = "clicked outside";
    }
    this.wasInside = false;
  }
18
J. Frankenstein

上記の答えは正しいですが、関連するコンポーネントからフォーカスを失った後に重いプロセスを実行している場合はどうでしょう。そのために、関連するコンポーネントのみからフォーカスを失った場合にのみフォーカスアウトイベントプロセスが発生する2つのフラグを持つソリューションを用意しました。

isFocusInsideComponent = false;
isComponentClicked = false;

@HostListener('click')
clickInside() {
    this.isFocusInsideComponent = true;
    this.isComponentClicked = true;
}

@HostListener('document:click')
clickout() {
    if (!this.isFocusInsideComponent && this.isComponentClicked) {
        // do the heavy process

        this.isComponentClicked = false;
    }
    this.isFocusInsideComponent = false;
}

これがお役に立てば幸いです。何か見逃している場合は私を修正します。

2
Rishanthakumar

https://www.npmjs.com/package/ng-click-outside packageからclickOutside()メソッドを使用できます

1
James Bond