狛ログ

2018年8月22日水曜日

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


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

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

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

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

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

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

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

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

import {
  Component,
  ChangeDetectionStrategy,
  OnInit,
  HostListener,
  ElementRef
} from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'move-homepage-header',
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './homepage-header.component.html'
})
export class HompageHeaderComponent implements OnInit {

  isShownCompanyPopUp = false;

  constructor(
    private eRef: ElementRef,
    private router: Router
  ) {}

  ngOnInit() {}

  @HostListener('document:click', ['$event'])
  onClickOut(event) {
    if (!this.eRef.nativeElement.contains(event.target)) {
      this.isShownCompanyPopUp = false;
    }
  }

  showCompanyPopup() {
    this.isShownCompanyPopUp = !this.isShownCompanyPopUp;
  }

  linkCompanyInfo() {
   this.isShownCompanyPopUp = false;
    this.router.navigateByUrl('/home/companyinfo');
  }

  linkCompanyMap() {
   this.isShownCompanyPopUp = false;
    this.router.navigateByUrl('/home/companymap');
  }

  linkPrivacyPolicy() {
   this.isShownCompanyPopUp = false;
    this.router.navigateByUrl('/home/privacypolicy');
  }
}

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

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

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


0 件のコメント:

コメントを投稿