[Angular學習紀錄] 屬性型指令@Directive()

Angular 的指令共分三種類型 :
  1. 組件(Component) : 也就是模板的指令,這是最常使用到的指令。
  2. 結構型指令(Structural directives) : 用來修改視圖的 "結構",例如添加或移除DOM布局,常用的指令如 NgIf 和 NgFor。
  3. 屬性指令(Attribute directives) : 用來改變視圖元件的 "外觀和行為",例如預設的背景色、滑過改變顏色,常用的指令如 NgStyle。
而 @Directive() 就是 "屬性指令" 的一種,下圖為本文範例的示意圖,先大概說明以下幾個操作情境,底下會有詳細的說明。
  • 設定載入時的預設背景色。
  • 設定滑鼠滑過的背景設,當滑鼠離開後恢復預設背景色。
  • 設定滑鼠點擊的背景設,當Click事件發生時變成指定背景色。



初始化 Directive指令


首先產生 highlight.directive.ts 檔,底下的程式碼運作後,若有 DOM 元素套用該指令,建構室內宣告該元素的背景色將會變成黃色,步驟說明如下。
  1. 建立新類別 HighlightDirective,並給予@Directive()裝飾器。
  2. @Directive(),給予 selector 名稱,該名稱為後續 DOM 元素要套用時的屬性,注意官網中有提到,名稱的命名盡量不要跟 html5 內的屬性名稱衝突,避免不避必要的 bug。
  3. 於建構子內注入( DI ) ElementRef,該類別會協助抓取目前套用的元素。
import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[myHighlight]'
})
export class HighlightDirective { 
  constructor(private el: ElementRef) {
    this.el.nativeElement.style.backgroundColor = "yellow";
  } 
}

接下來是產生每個TypeScript檔後都必須要做但很常忘記的事情,很重要、很重要、很重要,忘記定義將不會有任何效果,請記得去 app.module.ts 內定義該類別。
import { HighlightDirective } from './highlight.directive';

@NgModule({
  declarations: [
    AppComponent,
    HighlightDirective
  ],  
  bootstrap: [AppComponent]
})
export class AppModule { }

回到 app.component.html 檔案中,為 h1 元素套用剛剛定義的屬性指令,就可以看到載入畫面後,出現黃底背景的效果了。
<h1 myHighlight> Hello </h1>



加入輸入屬性


上面的範例中示範的方式是直接在建構子當中寫死的黃色字串,當然實務上大部分都是透過輸入屬性(@Input 說明參考先前文章說明)將所需要的屬性傳入,底下補充說明 @Input() 幾個使用情境。

  • @Input() clickColor : string,定義滑鼠 Click 事件的顏色,此為一般外部輸入的使用方式。
  • @Input('hoverColor') highlightColor: string,定義滑鼠 hover 事件的顏色,可以看到此處 Input 帶入一參數,此為定義外部呼叫的別名(不一定需要),若有定義別名,則外部使用只能呼叫別名
  • @Input('myHighlight') defaultColor: string,定義預設背景色,定義別名若等同於 Selector 的話,可直接套用該 Directive,並直接給予屬性值,這是一個簡易的語法 ,例如 <div myHighlight='red'></div>。
//定義外部呼叫的別名(不一定需要),若有定義別名,則外部使用只能呼叫別名。
@Input('hoverColor') highlightColor: string;

// 定義別名若等同於 Selector 的話,可直接套用該 Directive,並直接給予屬性值
@Input('myHighlight') defaultColor: string;

// 正常使用方式
@Input() clickColor: string;



加入 DOM 事件監聽


Angular 提供了 @HostListener() 裝飾器,透過此屬性指令帶入要監聽的 DOM 事件名稱當參數,Angular 會協助監聽宿主的 DOM Event,並在該事件發生時執行定義的工作,本範例中共監聽了 滑鼠滑過、滑鼠離開、滑鼠點擊三個事件,並分別改變為指定的顏色。
//定義滑鼠點下事件
@HostListener('click') onClick() {
this.highlight(this.clickColor || this.defaultColor);
}

//定義滑鼠進入事件
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || this.defaultColor);
}

//定義滑鼠離開事件
@HostListener('mouseleave') onMouseLeave() {
this.highlight(this.defaultColor);
}

//改變顏色函數
highlight(colorName: string) {
this.el.nativeElement.style.backgroundColor = colorName;
}



使用屬性指令


透過上文的實作,已經可以使用定義好的指令了,打開 app.component.html,將效果套上吧。
<h1 myHighlight="purple" hoverColor="red" clickColor="blue">
  Hello
</h1>

<h1 myHighlight="pink" hoverColor="lime" clickColor="dodgerblue">
  Lawrence Shen
</h1>



※ 小叮嚀,還記得建構子的生命週期比屬性還要早嗎? 因此若要設定預設的顏色,必須要在ngOnInit才會有效果喔。



本文撰寫時Angular版本為v4.0。

本文範例下載 : Github,使用Angular CLI。





留言