angular 內置了不少指令,可是這篇筆記主要記錄如何自定義指令。html
- 導入 Directive 裝飾器(而再也不是 Component), 指令帶有 @Directive 裝飾器。
- 導入所需符號 Input、TemplateRef 和 ViewContainerRef, 任何結構型指令都會用到以上三個(屬性型經常使用:ElementRef、HostListener)。
- 給指令類添加裝飾器。
- 設置 CSS 屬性選擇器 ,以便在模板中標識出這個指令該應用於哪一個元素。
// 建立指令的 CLI 命令
ng generate directive highlight
複製代碼
import { Directive } from '@angular/core';
@Directive({
// 定義一個 CSS 屬性型選擇器 [appHighlight], 一般帶前綴(除ng),如app等,確保它們不會與標準 HTML 屬性衝突
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor() { }
}
複製代碼
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
// [appHighlight]定義了一個CSS 屬性選擇器
// 屬性名應該拼寫成小駝峯形式,而且帶有一個前綴,如app。這個前綴不能用 ng,由於它只屬於 Angular 自己。
selector: '[appHighlight]'
})
export class HighlightDirective {
// ElementRef 經過其 nativeElement 屬性能夠直接訪問宿主 DOM 元素
constructor(private el: ElementRef) { }
// @Input 的參數中把該選擇器highlightColor指定爲別名appHighlight。
@Input('appHighlight') highlightColor: string;
// @HostListener 裝飾器訂閱某個屬性型指令所在的宿主 DOM 元素的事件
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
複製代碼
<p [appHighlight]="'orange'">Highlighted in orange</p>
複製代碼
結構型指令中星號()被放在指令的屬性名以前, Angular 會把星號()語法解開成
<ng-template>
app
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[appUnless]'})
export class UnlessDirective {
private hasView = false;
// 使用TemplateRef取得 <ng-template> 的內容,並經過ViewContainerRef來訪問這個視圖容器
constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
// 沒有人會讀取 appUnless 屬性,所以它不須要定義 getter。
@Input() set appUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
複製代碼
<p *appUnless="condition" class="unless a">1111</p>
複製代碼