狛ログ

2018年8月22日水曜日

windowやdocumentのイベントをAngularで使う。(HostListener)


オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

Angularは、自コンポーネント内の項目についてのイベントは簡単に定義出来ます。

[View側]
  1. <button class="button_close" type="button" (click)="close()">閉じる</button>

[Component側]
  1. close() {
  2. // ここに処理を記載
  3. }

しかし、自コンポーネント以外のイベントを取るとなると、ちょっと工夫が要ります。

例えば、下記のような要素があったとします。

「Company」リンクをクリックすれば、吹き出しが出るのは簡単に実装出来ますが、
『吹き出し以外をクリックしたら、吹き出しを閉じる』はどうやって実装したら良いでしょうか?

こんな時に、「HostListener」を使用します。
その名の通り、HostのイベントをListen出来ます。

  1. import {
  2. Component,
  3. ChangeDetectionStrategy,
  4. OnInit,
  5. HostListener,
  6. ElementRef
  7. } from '@angular/core';
  8. import { Router } from '@angular/router';
  9.  
  10. @Component({
  11. selector: 'move-homepage-header',
  12. changeDetection: ChangeDetectionStrategy.OnPush,
  13. templateUrl: './homepage-header.component.html'
  14. })
  15. export class HompageHeaderComponent implements OnInit {
  16.  
  17. isShownCompanyPopUp = false;
  18.  
  19. constructor(
  20. private eRef: ElementRef,
  21. private router: Router
  22. ) {}
  23.  
  24. ngOnInit() {}
  25.  
  26. @HostListener('document:click', ['$event'])
  27. onClickOut(event) {
  28. if (!this.eRef.nativeElement.contains(event.target)) {
  29. this.isShownCompanyPopUp = false;
  30. }
  31. }
  32.  
  33. showCompanyPopup() {
  34. this.isShownCompanyPopUp = !this.isShownCompanyPopUp;
  35. }
  36.  
  37. linkCompanyInfo() {
  38. this.isShownCompanyPopUp = false;
  39. this.router.navigateByUrl('/home/companyinfo');
  40. }
  41.  
  42. linkCompanyMap() {
  43. this.isShownCompanyPopUp = false;
  44. this.router.navigateByUrl('/home/companymap');
  45. }
  46.  
  47. linkPrivacyPolicy() {
  48. this.isShownCompanyPopUp = false;
  49. this.router.navigateByUrl('/home/privacypolicy');
  50. }
  51. }

HostListenerのimportは忘れないように記載して下さい。
さて、肝心の部分を抜粋すると・・・・
  1. @HostListener('document:click', ['$event'])
  2. onClickOut(event) {
  3. if (!this.eRef.nativeElement.contains(event.target)) {
  4. this.isShownCompanyPopUp = false;
  5. }
  6. }

今回は、「documentのclickイベント」を使用しています。
ただ、これだと、吹き出しの中のクリックイベントまで対象になってしまうので、
自コンポーネント内は除外し、『自コンポーネント内以外をクリック』のイベントを取る事を実現しています。

いかがでしょうか?
この方法で、windowのresizeイベントも取れると思います。


0 件のコメント:

コメントを投稿