Angular 2 的指令分爲如下三種:html
組件(Component directive):用於構建UI組件,繼承於 Directive 類typescript
屬性指令(Attribute directive): 用於改變組件的外觀或行爲segmentfault
結構指令(Structural directive): 用於動態添加或刪除DOM元素來改變DOM佈局app
組件示例:less
import { Component } from '@angular/core'; @Component({ selector: 'my-app', // 定義組件在HTML代碼中匹配的標籤 template: `<h1>Hello {{name}}</h1>`, // 指定組件關聯的內聯模板 }) export class AppComponent { name = 'Angular'; }
1.ngStyle指令: 用於設定給定 DOM 元素的 style
屬性佈局
綁定常量this
<div [ngStyle]="{'background-color': 'green'}"></div>
綁定表達式spa
<div [ngStyle]="{'background-color': person.country === 'UK' ? 'green' : 'red'}">
具體示例:code
import { Component } from '@angular/core'; @Component({ selector: 'ngstyle-example', template: `<h4>NgStyle</h4> <ul *ngFor="let person of people"> <li [ngStyle]="{'color': getColor(person.country)}"> {{ person.name }} ({{person.country}}) </li> </ul> ` }) export class NgStyleExampleComponent { getColor(country: string) { switch (country) { case 'CN': return 'red'; case 'USA': return 'blue'; case 'UK': return 'green'; } } people: any[] = [ { name: "Semlinker", country: 'CN' }, { name: "Donald John Trump", country: 'USA' }, { name: "Daniel Manson", country: 'UK' } ]; }
上面的例子,除了使用 ngStyle
指令,咱們還能夠使用 [style.<property>]
的語法:htm
<ul *ngFor="let person of people"> <li [style.color]="getColor(person.country)"> {{ person.name }} ({{person.country}}) </li> </ul>
2.ngClass指令:用於動態的設定 DOM 元素的 CSS class
綁定常量
<div [ngClass]="{'text-success': true }"></div>
綁定表達式
<div [ngClass]="{'text-success': person.country === 'CN'}"></div>
具體示例:
import { Component } from '@angular/core'; @Component({ selector: 'ngclass-example', template: ` <style> .text-success { color: green } .text-primary { color: red } .text-secondary { color: blue } </style> <h4>NgClass</h4> <ul *ngFor="let person of people"> <li [ngClass]="{ 'text-success': person.country === 'UK', 'text-primary': person.country === 'CN', 'text-secondary': person.country === 'USA' }"> {{ person.name }} ({{person.country}}) </li> </ul> `, }) export class NgClassExampleComponent { people: any[] = [ { name: "Semlinker", country: 'CN' }, { name: "Donald John Trump", country: 'USA' }, { name: "Daniel Manson", country: 'UK' } ]; }
1.ngIf指令:根據表達式的值,顯示或移除元素
<div *ngIf="person.country === 'CN'">{{ person.name }} ({{person.country}})</div>
2.ngFor指令:使用可迭代的每一個項做爲模板的上下文來重複模板,相似於 Ng 1.x 中的 ng-repeat
指令
<div *ngFor="let person of people">{{person.name}}</div>
3.ngSwitch指令:它包括兩個指令,一個屬性指令和一個結構指令。它相似於 JavaScript 中的 switch
語句
<ul [ngSwitch]='person.country'> <li *ngSwitchCase="'UK'" class='text-success'> {{ person.name }} ({{person.country}}) </li> <li *ngSwitchCase="'USA'" class='text-secondary'> {{ person.name }} ({{person.country}}) </li> <li *ngSwitchDefault class='text-primary'> {{ person.name }} ({{person.country}}) </li> </ul>
經過上面的例子,能夠看出結構指令和屬性指令的區別。結構指令是以 *
做爲前綴,這個星號實際上是一個語法糖。它是 ngIf
和 ngFor
語法的一種簡寫形式。Angular 引擎在解析時會自動轉換成 <template>
標準語法。
1.ngIf指令:
<template [ngIf]='condition'> <p>I am the content to show</p> </template>
2.ngFor指令:
<template ngFor [ngForOf]="people" let-person> <div> {{ person.name }} ({{person.country}}) </div> </template>
3.ngSwitch指令:
<ul [ngSwitch]='person.country'> <template [ngSwitchCase]="'UK'"> <li class='text-success'> {{ person.name }} ({{person.country}}) </li> </template> <template [ngSwitchCase]="'USA'"> <li class='text-secondary'> {{ person.name }} ({{person.country}}) </li> </template> <template [ngSwitchDefault]> <li class='text-primary'> {{ person.name }} ({{person.country}}) </li> </template> </ul>
1.ngIf指令定義:
@Directive({selector: '[ngIf]'}) export class NgIf {}
2.ngFor指令定義:
@Directive({selector: '[ngFor][ngForOf]'}) export class NgForOf<T> implements DoCheck, OnChanges {}
3.ngSwitch指令定義:
@Directive({selector: '[ngSwitch]'}) export class NgSwitch {} @Directive({selector: '[ngSwitchCase]'}) export class NgSwitchCase implements DoCheck {} @Directive({selector: '[ngSwitchDefault]'}) export class NgSwitchDefault {}
指令功能描述:該指令用於在用戶點擊宿主元素時,根據輸入的背景顏色,更新宿主元素的背景顏色。宿主元素的默認顏色是黃色。
1.指令實現
import {Directive, Input, ElementRef, Renderer, HostListener} from "@angular/core"; @Directive({ selector: '[exeBackground]' }) export class ExeBackgroundDirective { private _defaultColor = 'yellow'; @Input('exeBackground') backgroundColor: string; // 輸入屬性,用於設置元素的背景顏色 constructor(private elementRef: ElementRef, private renderer: Renderer) { this.setStyle(this._defaultColor); } @HostListener('click') onClick() { // 監聽宿主元素的點擊事件,設置元素背景色 this.setStyle(this.backgroundColor || this._defaultColor); } private setStyle(color: string) { // 調用renderer對象提供的API設置元素的背景顏色 this.renderer.setElementStyle(this.elementRef.nativeElement, 'backgroundColor', color); } }
2.指令應用:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1 [exeBackground]="'red'">Hello {{name}}</h1>`, }) export class AppComponent { name = 'Angular'; }
指令功能描述:該指令實現 ngIf
指令相反的效果,當指令的輸入條件爲 Falsy
值時,顯示DOM元素。
1.指令實現
@Directive({ selector: '[exeUnless]' }) export class UnlessDirective { @Input('exeUnless') set condition(newCondition: boolean) { if (!newCondition) { // 建立模板對應的內嵌視圖 this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { } }
2.指令應用
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1 [exeBackground]="'red'" *exeUnless="condition">Hello {{name}}</h1>`, }) export class AppComponent { name = 'Angular'; condition: boolean = false; }
1.自定義屬性指令中的 ElementRef
與 Renderer
的做用
爲了可以支持跨平臺,Angular 2 經過抽象層封裝了不一樣平臺的差別,統一了 API 接口。如定義了抽象類 Renderer 、抽象類 RootRenderer 等。此外還定義瞭如下引用類型:ElementRef、TemplateRef、ViewRef 、ComponentRef 和 ViewContainerRef 等。
詳細內容請參考 - Angular 2 ElementRef
2.自定義結構指令中的 TemplateRef
與 ViewContainerRef
的做用
TemplateRef:用於表示內嵌的 template 模板元素,經過 TemplateRef 實例,咱們能夠方便建立內嵌視圖(Embedded Views),且能夠輕鬆地訪問到經過 ElementRef 封裝後的 nativeElement。須要注意的是組件視圖中的 template 模板元素,通過渲染後會被替換成 comment 元素。
ViewContainerRef:用於表示一個視圖容器,可添加一個或多個視圖。通ViewContainerRef 實例,咱們能夠基於 TemplateRef 實例建立內嵌視圖,並能指定內嵌視圖的插入位置,也能夠方便對視圖容器中已有的視圖進行管理。簡而言之,ViewContainerRef 的主要做用是建立和管理內嵌視圖或組件視圖。
詳細內容請參考 - Angular 2 TemplateRef & ViewContainerRef
3.Angular 2 中指令與組件的關係
組件繼承於指令,並擴展了與 UI 視圖相關的屬性,如 template、styles、animations、encapsulation 等。
詳細內容請參考 - Angular 2 Directive Lifecycle
本文主要介紹了 Angular 2 中的指令,經過具體示例介紹了 Angular 2 常見內建指令的使用方式和區別。最終,咱們經過自定義屬性指令和自定義結構指令兩個示例,展現瞭如何開發自定義指令。