W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
指令是為 Angular 應用程序中的元素添加額外行為的類。使用 Angular 的內(nèi)置指令,你可以管理表單、列表、樣式以及要讓用戶看到的任何內(nèi)容。
要查看包含本指南中代碼的可工作范例,請參閱現(xiàn)場演練 / 下載范例。
Angular 指令的不同類型如下:
本指南涵蓋了內(nèi)置的屬性型指令和結構型指令。
屬性型指令會監(jiān)聽并修改其它 HTML 元素和組件的行為、Attribute 和 Property。
許多 NgModule(例如 ?RouterModule
?和 ?FormsModule
?都定義了自己的屬性型指令。最常見的屬性型指令如下:
NgClass
?—— 添加和刪除一組 CSS 類。NgStyle
?—— 添加和刪除一組 HTML 樣式。NgModel
?—— 將數(shù)據(jù)雙向綁定添加到 HTML 表單元素。內(nèi)置指令只會使用公開 API。它們不會訪問任何無法被其它指令訪問的私有 API。
用 ?ngClass
?同時添加或刪除多個 CSS 類。
要添加或刪除單個類,請使用類綁定而不是 ?NgClass
?。
在要設置樣式的元素上,添加 ?[ngClass]
? 并將其設置為等于某個表達式。在這里,是在 ?app.component.ts
? 中將 ?isSpecial
?設置為布爾值 ?true
?。因為 ?isSpecial
?為 ?true
?,所以 ?ngClass
?就會把 ?special
?類應用于此 ?<div>
? 上。
<!-- toggle the "special" class on/off with a property -->
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
NgClass
?與方法一起使用,請將方法添加到組件類中。在下面的示例中,?setCurrentClasses()
? 使用一個對象來設置屬性 ?currentClasses
?,該對象根據(jù)另外三個組件屬性為 ?true
?或 ?false
?來添加或刪除三個 CSS 類。該對象的每個鍵(key)都是一個 CSS 類名。如果鍵為 ?true
?,則 ?ngClass
?添加該類。如果鍵為 ?false
?,則 ?ngClass
?刪除該類。
currentClasses: Record<string, boolean> = {};
/* . . . */
setCurrentClasses() {
// CSS classes: added/removed per current state of component properties
this.currentClasses = {
saveable: this.canSave,
modified: !this.isUnchanged,
special: this.isSpecial
};
}
ngClass
?屬性綁定到 ?currentClasses
?,根據(jù)它來設置此元素的 CSS 類:<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div>
在這個例子中,Angular 會在初始化以及發(fā)生更改的情況下應用這些類。完整的示例會在 ngOnInit()
中進行初始化以及通過單擊按鈕更改相關屬性時調(diào)用 setCurrentClasses()
。這些步驟對于實現(xiàn) ngClass
不是必需的。有關更多信息,請參見
app.component.ts
和 app.component.html
。
可以用 ?NgStyle
?根據(jù)組件的狀態(tài)同時設置多個內(nèi)聯(lián)樣式。
NgStyle
?,請向組件類添加一個方法。在下面的例子中,?setCurrentStyles()
? 方法基于該組件另外三個屬性的狀態(tài),用一個定義了三個樣式的對象設置了 ?currentStyles
?屬性。
currentStyles: Record<string, string> = {};
/* . . . */
setCurrentStyles() {
// CSS styles: set per current state of component properties
this.currentStyles = {
'font-style': this.canSave ? 'italic' : 'normal',
'font-weight': !this.isUnchanged ? 'bold' : 'normal',
'font-size': this.isSpecial ? '24px' : '12px'
};
}
ngStyle
?屬性綁定到 ?currentStyles
?。<div [ngStyle]="currentStyles">
This div is initially italic, normal weight, and extra large (24px).
</div>
在這個例子中,Angular 會在初始化以及發(fā)生更改的情況下應用這些類。完整的示例會在 ngOnInit()
中進行初始化以及通過單擊按鈕更改相關屬性時調(diào)用 setCurrentClasses()
。這些步驟對于實現(xiàn) ngClass
不是必需的。有關更多信息,請參見
app.component.ts
和 app.component.html
。
可以用 ?NgModel
?指令顯示數(shù)據(jù)屬性,并在用戶進行更改時更新該屬性。
FormsModule
?,并將其添加到 NgModule 的 ?imports
?列表中。import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular
/* . . . */
@NgModule({
/* . . . */
imports: [
BrowserModule,
FormsModule // <--- import into the NgModule
],
/* . . . */
})
export class AppModule { }
<form>
? 元素上添加 ?[(ngModel)]
? 綁定,并將其設置為等于此屬性,這里是 ?name
?。<label for="example-ngModel">[(ngModel)]:</label>
<input [(ngModel)]="currentItem.name" id="example-ngModel">
此 ?[(ngModel)]
? 語法只能設置數(shù)據(jù)綁定屬性。
要自定義配置,你可以編寫可展開的表單,該表單將屬性綁定和事件綁定分開。使用屬性綁定來設置屬性,并使用事件綁定來響應更改。以下示例將 ?<input>
? 值更改為大寫:
<input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">
這里是所有這些變體的動畫,包括這個大寫轉(zhuǎn)換的版本:
?NgModel
?指令適用于?ControlValueAccessor
?支持的元素。Angular 為所有基本 HTML 表單元素提供了值訪問器。
要將 ?[(ngModel)]
? 應用于非表單型內(nèi)置元素或第三方自定義組件,必須編寫一個值訪問器。
編寫 Angular 組件時,如果根據(jù) Angular 的雙向綁定語法命名 value 和 event 屬性,則不需要用值訪問器(ControlValueAccessor)或 ?
NgModel
?。
結構型指令的職責是 HTML 布局。 它們塑造或重塑 DOM 的結構,這通常是通過添加、移除和操縱它們所附加到的宿主元素來實現(xiàn)的。
本節(jié)會介紹最常見的內(nèi)置結構型指令:
NgIf
?—— 從模板中創(chuàng)建或銷毀子視圖。NgFor
?—— 為列表中的每個條目重復渲染一個節(jié)點。NgSwitch
?—— 一組在備用視圖之間切換的指令。可以將 ?NgIf
?指令應用于宿主元素來添加或刪除元素。
如果 ?NgIf
?為 ?false
?,則 Angular 將從 DOM 中移除一個元素及其后代。然后,Angular 會銷毀其組件,從而釋放內(nèi)存和資源。
要添加或刪除元素,請在以下示例 ?*ngIf
? 綁定到條件表達式,例如 ?isActive
?
<app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>
當 ?isActive
?表達式返回真值時,?NgIf
?會把 ?ItemDetailComponent
?添加到 DOM 中。當表達式為假值時,?NgIf
?會從 DOM 中刪除 ?ItemDetailComponent
?并銷毀該組件及其所有子組件。
默認情況下,?NgIf
?會阻止顯示已綁定到空值的元素。
要使用 ?NgIf
?保護 ?<div>
?,請將 ?*ngIf="yourProperty"
? 添加到此 ?<div>
?。在下面的例子中,?currentCustomer
?名字出現(xiàn)了,是因為確實存在一個 ?currentCustomer
?。
<div *ngIf="currentCustomer">Hello, {{currentCustomer.name}}</div>
但是,如果該屬性為 ?null
?,則 Angular 就不會顯示 ?<div>
?。在這個例子中,Angular 就不會顯示 ?nullCustomer
?,因為它為 ?null
?。
<div *ngIf="nullCustomer">Hello, <span>{{nullCustomer}}</span></div>
可以用 ?NgFor
?來指令顯示條目列表。
let item of items
? 賦值給 ?*ngFor
?。<div *ngFor="let item of items">{{item.name}}</div>
字符串 ?"let item of items"
? 會指示 Angular 執(zhí)行以下操作:
items
?中的每個條目存儲在局部循環(huán)變量 ?item
?中"let item of items"
? 轉(zhuǎn)換為環(huán)繞宿主元素的 ?<ng-template>
?item
?復寫這個 ?<ng-template>
?要復寫某個組件元素,請將 ?*ngFor
? 應用于其選擇器。在以下示例中,選擇器為 ?<app-item-detail>
?。
<app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail>
你可以在以下位置引用模板輸入變量,例如 ?item
?:
ngFor
?的宿主元素中以下示例首先在插值中引用 ?item
?,然后將它通過綁定傳遞給 ?<app-item-detail>
? 組件的 ?item
?屬性。
<div *ngFor="let item of items">{{item.name}}</div>
<!-- . . . -->
<app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail>
可以獲取 ?*ngFor
? 的 ?index
?,并在模板中使用它。
在 ?*ngFor
? 中,添加一個分號和 ?let i=index
? 簡寫形式。下面的例子中把 ?index
?取到一個名為 ?i
? 的變量中,并將其與條目名稱一起顯示。
<div *ngFor="let item of items; let i=index">{{i + 1}} - {{item.name}}</div>
?NgFor
?指令上下文的 ?index
?屬性在每次迭代中都會返回該條目的從零開始的索引號。
Angular 會將此指令轉(zhuǎn)換為 ?<ng-template>
?,然后反復使用此模板為列表中的每個 ?item
?創(chuàng)建一組新的元素和綁定。
要在特定條件為 true 時復寫 HTML 塊,請將 ?*ngIf
? 放在 ?*ngFor
? 元素的容器元素上。它們之一或兩者都可以是 ?<ng-container>
?,這樣你就不必引入額外的 HTML 層次了。
由于結構型指令會在 DOM 中添加和刪除節(jié)點,因此每個元素只能應用一個結構型指令。
通過跟蹤對條目列表的更改,可以減少應用程序?qū)Ψ掌鞯恼{(diào)用次數(shù)。使用 ?*ngFor
? 的 ?trackBy
?屬性,Angular 只能更改和重新渲染已更改的條目,而不必重新加載整個條目列表。
NgFor
?應該跟蹤的值。這個例子中,該值是英雄的 ?id
?。如果瀏覽器已經(jīng)渲染過此 ?id
?,Angular 就會跟蹤它,而不會重新向服務器查詢相同的 ?id
?。trackByItems(index: number, item: Item): number { return item.id; }
trackBy
?設置為 ?trackByItems()
? 方法。<div *ngFor="let item of items; trackBy: trackByItems">
({{item.id}}) {{item.name}}
</div>
更改這些 ID 會使用新的 ?item.id
? 創(chuàng)建新的條目。在下面的 ?trackBy
?效果演示中,Reset items 會創(chuàng)建一些具有和以前相同的 ?item.id
? 的新條目。
trackBy
?,這些按鈕都會觸發(fā)完全的 DOM 元素替換。trackBy
?,則只有修改了 ?id
?的按鈕才會觸發(fā)元素替換。
Angular 的 ?<ng-container>
? 是一個分組元素,它不會干擾樣式或布局,因為 Angular 不會將其放置在 DOM 中。
當沒有單個元素承載指令時,可以使用 ?<ng-container>
?。
這是使用 ?<ng-container>
? 的條件化段落。
<p>
I turned the corner
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
FormsModule
?中導入 ?ngModel
?指令。FormsModule
?添加到相關 Angular 模塊的 imports 部分。<option>
?,請將 ?<option>
? 包裹在 ?<ng-container>
? 中。<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
就像 JavaScript 的 ?switch
?語句一樣。?NgSwitch
?會根據(jù)切換條件顯示幾個可能的元素中的一個。Angular 只會將選定的元素放入 DOM。
?NgSwitch
?是一組指令(共三個):
NgSwitch
?—— 一個屬性型指令,它更改其伴生指令的行為。NgSwitchCase
?—— 結構型指令,當其綁定值等于開關值時將其元素添加到 DOM 中,而在其不等于開關值時將其綁定值移除。NgSwitchDefault
?—— 結構型指令,當沒有選中的 ?NgSwitchCase
?時,將其宿主元素添加到 DOM 中。<div>
?)上,把 ?[ngSwitch]
? 綁定到一個返回開關值的表達式(例如 ?feature
?)。盡管這個例子中 ?feature
?值是字符串,但此開關值可以是任何類型。*ngSwitchCase
? 和 ?*ngSwitchDefault
?。<div [ngSwitch]="currentItem.feature">
<app-stout-item *ngSwitchCase="'stout'" [item]="currentItem"></app-stout-item>
<app-device-item *ngSwitchCase="'slim'" [item]="currentItem"></app-device-item>
<app-lost-item *ngSwitchCase="'vintage'" [item]="currentItem"></app-lost-item>
<app-best-item *ngSwitchCase="'bright'" [item]="currentItem"></app-best-item>
<!-- . . . -->
<app-unknown-item *ngSwitchDefault [item]="currentItem"></app-unknown-item>
</div>
currentItem
?以便可以在 ?[ngSwitch]
? 表達式中使用它。currentItem!: Item;
item
?,該屬性會綁定到父組件的 ?currentItem
?。以下兩個片段顯示了父組件和其中一個子組件。其他子組件與 ?StoutItemComponent
?中的相同。export class StoutItemComponent {
@Input() item!: Item;
}
Switch 指令也同樣適用于內(nèi)置 HTML 元素和 Web Component。 比如,你可以像下面的例子中一樣把 ?<app-best-item>
? 分支替換為 ?<div>
?。
<div *ngSwitchCase="'bright'"> Are you as bright as {{currentItem.name}}?</div>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: