Angular 2 HostListener & HostBinding

閱讀 Angular 6/RxJS 最新教程,請訪問 前端修仙之路

Host Element

在介紹 HostListener 和 HostBinding 屬性裝飾器以前,咱們先來了解一下 host element (宿主元素)。html

宿主元素的概念同時適用於指令和組件。對於指令來講,這個概念是至關簡單的。應用指令的元素,就是宿主元素。假設咱們已聲明瞭一個 HighlightDirective 指令 (selector: '[exeHighlight]'):前端

<p exeHighlight>
   <span>高亮的文本</span>
</p>

上面 html 代碼中,p 元素就是宿主元素。若是該指令應用於自定義組件中如:typescript

<exe-counter exeHighlight>
    <span>高亮的文本</span>
</exe-counter>

此時 exe-counter 自定義元素,就是宿主元素。瀏覽器

HostListener

HostListener 是屬性裝飾器,用來爲宿主元素添加事件監聽。app

HostListenerDecorator 裝飾器定義

export interface HostListenerDecorator {
    (eventName: string, args?: string[]): any;
    new (eventName: string, args?: string[]): any;
}

HostListenerDecorator 裝飾器應用

counting.directive.tside

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

@Directive({
    selector: 'button[counting]'
})
class CountClicks {
    numberOfClicks = 0;

    @HostListener('click', ['$event.target'])
    onClick(btn: HTMLElement) {
        console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
    }
}

app.component.tsui

import { Component} from '@angular/core';

@Component({
  selector: 'exe-app',
  styles: [`
    button {
      background: blue;
      color: white;
      border: 1px solid #eee;
    }
  `],
  template: `
    <button counting>增長點擊次數</button>
  `
})
export class AppComponent {}

以上代碼運行後瀏覽器顯示的結果:this

圖片描述

此外,咱們也能夠監聽宿主元素外,其它對象產生的事件,如 windowdocument 對象。具體示例以下:spa

highlight.directive.tscode

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

@Directive({
    selector: '[exeHighlight]'
})
export class ExeHighlight {
    constructor(private el: ElementRef, private renderer: Renderer) { }

    @HostListener('document:click', ['$event'])
    onClick(btn: Event) {
        if (this.el.nativeElement.contains(event.target)) {
            this.highlight('yellow');
        } else {
            this.highlight(null);
        }
    }

    highlight(color: string) {
        this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor', color);
    }
}

app.component.ts

import { Component} from '@angular/core';

@Component({
  selector: 'exe-app',
  template: `
    <h4 exeHighlight>點擊該區域,元素會被高亮。點擊其它區域,元素會取消高亮</h4>
  `
})
export class AppComponent {}

以上代碼運行後瀏覽器顯示的結果:

圖片描述

Host Event Listener

咱們也能夠在指令的 metadata 信息中,設定宿主元素的事件監聽信息,具體示例以下:

counting.directive.ts

import { Directive } from '@angular/core';

@Directive({
    selector: 'button[counting]',
    host: {
      '(click)': 'onClick($event.target)'
    }
})
export class CountClicks {
    numberOfClicks = 0;

    onClick(btn: HTMLElement) {
        console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
    }
}

HostBinding

HostBinding 是屬性裝飾器,用來動態設置宿主元素的屬性值。

HostBinding 裝飾器定義

export interface HostBindingDecorator {
    (hostPropertyName?: string): any;
    new (hostPropertyName?: string): any;
}

HostBinding 裝飾器應用

button-press.directive.ts

import { Directive, HostBinding, HostListener } from '@angular/core';

@Directive({
    selector: '[exeButtonPress]'
})
export class ExeButtonPress {
    @HostBinding('attr.role') role = 'button';
    @HostBinding('class.pressed') isPressed: boolean;

    @HostListener('mousedown') hasPressed() {
        this.isPressed = true;
    }
    @HostListener('mouseup') hasReleased() {
        this.isPressed = false;
    }
}

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'exe-app',
  styles: [`
    button {
      background: blue;
      color: white;
      border: 1px solid #eee;
    }
    button.pressed {
      background: red;
    }
  `],
  template: `
    <button exeButtonPress>按下按鈕</button>
  `
})
export class AppComponent { }

以上代碼運行後瀏覽器顯示的結果:

圖片描述

Host Property Bindings

咱們也能夠在指令的 metadata 信息中,設定宿主元素的屬性綁定信息,具體示例以下:

button-press.directive.ts

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

@Directive({
    selector: '[exeButtonPress]',
    host: {
      'role': 'button',
      '[class.pressed]': 'isPressed'
    }
})
export class ExeButtonPress {
    isPressed: boolean;

    @HostListener('mousedown') hasPressed() {
        this.isPressed = true;
    }
    @HostListener('mouseup') hasReleased() {
        this.isPressed = false;
    }
}

我有話說

1.宿主元素屬性和事件綁定風格指南

優先使用 @HostListener 和 @HostBinding ,而不是 @Directive 和 @Component 裝飾器的 host 屬性:

對於關聯到 @HostBinding 的屬性或關聯到 @HostListener 的方法,要修改時,只需在指令類中的一個地方修改。 若是使用元數據屬性 host,你就得在組件類中修改屬性聲明的同時修改相關的元數據。

詳細信息請參考 - Angular 2 風格指南 - STYLE 06-03

相關文章
相關標籤/搜索