Angular - Directive (2/2)

  • 147
  • 0
  • 2018-05-03

在Directive內 加入@HostListener,監聽來源Element的事件

實作教學網站 內的範例

我們可以自己用addEventListener來監聽事件是沒有問題的,不過需要注意的是,由於Angular2是一個SPA應用程式,

因此Element隨時會動態的被產生或消滅,如果我們沒有在Element被消滅時取消監聽的話,長久下來容易造成memory leaks的問題,

而@HostListener則可以幫我們解決這個問題,在Element被消滅時自動取消監聽!

以上說明取自教學網站的說明內容

現在要練習加入 @HostListener 來監聽Element的事件

import { Directive, ElementRef, Renderer, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[appBsbutton]'
})
export class BsbuttonDirective {

  @Input() appBsbutton;
  @Input() mouseDownClass; //mouse Click的時候會改變的Input

  //注入 ElementRef,來取得目前使用directive的element
  constructor(private ele: ElementRef, private renderer: Renderer) { }

  ngOnInit() {
    // 如果不確定ele是不是HTMLElement,就改用renderer來協助設定樣式
    this.appBsbutton = this.appBsbutton || 'primary';
    this.mouseDownClass = this.mouseDownClass || 'danger';
    this.renderer.setElementClass(this.ele.nativeElement, 'btn', true);
    this.renderer.setElementClass(this.ele.nativeElement, `btn-${this.appBsbutton}`, true);
  }

  //加入 @HostListener mouseDown
  @HostListener('mousedown') onmousedown() {
    //移除原來的bs class
    this.renderer.setElementClass(this.ele.nativeElement, `btn-${this.appBsbutton}`, false);
    // 加入mouseDown的bs class
    this.renderer.setElementClass(this.ele.nativeElement, `btn-${this.mouseDownClass}`, true);
  }

  //Mouse Up
  @HostListener('mouseup') onmouseup() {
    //Remove mouseDown bs class
    this.renderer.setElementClass(this.ele.nativeElement, `btn-${this.mouseDownClass}`, false);
    //加入原來的bs class
    this.renderer.setElementClass(this.ele.nativeElement, `btn-${this.appBsbutton}`, true);
  }
}

監聽事件的重點是:

MouseDown 跟 MouseUp 的BS class 切換

在HTML的地方改為多給一個@Input()

<button appBsbutton="danger" mouseDownClass="primary">Danger</button>
<button appBsbutton="info" mouseDownClass="success">Info</button>