官網地址:https://angular.cn/guide/forms-overview
目錄
一、表單簡介
1.Angular提供了兩種不同的方法來通過表單處理用戶輸入:響應式表單和模板驅動表單。兩者都從視圖中捕獲用戶輸入事件、驗證用戶輸入、創建表單模型、修改數據模型、並提供跟蹤這些更改的途徑。
不過,響應式表單和模板驅動表單在如何處理和管理表單和表單數據方面有所不同。各有優勢。
一般來說:
-
響應式表單更健壯:它們的可擴展性、可複用性和可測試性更強。 如果表單是應用中的關鍵部分,或者你已經準備使用響應式編程模式來構建應用,請使用響應式表單。
-
模板驅動表單在往應用中添加簡單的表單時非常有用,比如郵件列表的登記表單。它們很容易添加到應用中,但是不像響應式表單那麼容易擴展。如果你有非常基本的表單需求和簡單到能用模板管理的邏輯,請使用模板驅動表單。
-
下表總結了響應式表單和模板驅動表單之間的一些關鍵差異。
響應式
模板驅動
建立(表單模式)
顯式,在組件類中創建。
隱式,由組件創建。
數據模式
結構化
非結構化
可預測性
同步
異步
表單驗證
函數
指令
可變性
不可變
可變
可伸縮性
訪問底層 API
在 API 之上的抽象
共同基礎
響應式表單和模板驅動表單共享了一些底層構造塊。
-
FormControl
實例用於追蹤單個表單控件的值和驗證狀態。 -
FormGroup
用於追蹤一個表單控件組的值和狀態。 -
FormArray
用於追蹤表單控件數組的值和狀態。 -
ControlValueAccessor
用於在 Angular 的FormControl
實例和原生 DOM 元素之間創建一個橋樑。
權威數據源負責提供在指定時間點上表單元素的值和狀態。在響應式表單中,表單模式充當權威數據源。上例中的表單模型就是 FormControl
的實例。
建立表單模型
響應式表單和模板驅動表單都是用表單模型來跟蹤 Angular 表單和表單輸入元素之間值的變化。下面的例子展示瞭如何定義和創建表單模型。
在響應式表單中建立
下面是一個帶有輸入字段的組件,它使用響應式表單實現了單個控件。
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-reactive-favorite-color',
template: `
Favorite Color: <input type="text" [formControl]="favoriteColorControl">
`
})
export class FavoriteColorComponent {
favoriteColorControl = new FormControl('');
}
權威數據源負責提供在指定時間點上表單元素的值和狀態。在響應式表單中,表單模式充當權威數據源。上例中的表單模型就是 FormControl
的實例。
在響應式表單中,表單模型是顯式定義在組件類中的。接着,響應式表單指令(這裏是 FormControlDirective
)會把這個現有的表單控件實例通過數據訪問器(ControlValueAccessor
的實例)來指派給視圖中的表單元素。
在模板驅動表單中建立
下面是同一個帶有輸入字段的組件,它使用模板驅動表單實現了單個控件。
import { Component } from '@angular/core';
@Component({
selector: 'app-template-favorite-color',
template: `
Favorite Color: <input type="text" [(ngModel)]="favoriteColor">
`
})
export class FavoriteColorComponent {
favoriteColor = '';
}
在模板驅動表單中,權威數據源是模板。
表單模型的抽象促進了結構的簡化。模板驅動表單的 NgModel
指令負責創建和管理指定表單元素上的表單控件實例。它不那麼明顯,但你不必再直接操縱表單模型了。
表單中的數據流
當在 Angular 中構建表單時,理解框架如何處理來自用戶或程序化修改的數據流是非常重要的。 在處理表單輸入時,響應式表單和模板驅動表單遵循兩種不同的策略。下面的數據流範例從以前的 "喜歡的顏色" 輸入框開始,展示了它在響應式表單中的工作方式與模板驅動表單相比有何不同。
響應式表單中的數據流
如前所述,在響應式表單中,視圖中的每個表單元素都直接鏈接到一個表單模型(FormControl
實例)。 從視圖到模型的修改以及從模型到視圖的修改都是同步的,不依賴於所呈現的 UI。下面的圖示使用了同一個 "喜歡的顏色" 範例,來演示當輸入字段的值的變更來自視圖和來自模型時,數據如何流動。
下面這些步驟列出了 "從視圖到模型" 數據流的梗概。
-
最終用戶在輸入框元素中鍵入了一個值,這裏是 "Blue"。
-
這個輸入框元素會發出一個帶有最新值的 "input" 事件。
-
這個控件值訪問器
ControlValueAccessor
會監聽表單輸入框元素上的事件,並立即把新值傳給FormControl
實例。 -
FormControl
實例會通過valueChanges
這個可觀察對象發出這個新值。 -
valueChanges
的任何一個訂閱者都會收到這個新值。
下面這些步驟列出了從模型到視圖的數據流的梗概。
-
favoriteColorControl.setValue()
方法被調用,它會更新這個FormControl
的值。 -
FormControl
實例會通過valueChanges
這個可觀察對象發出新值。 -
valueChanges
的任何訂閱者都會收到這個新值。 -
該表單輸入框元素上的控件值訪問器會把控件更新爲這個新值。
模板驅動表單中的數據流
在模板驅動表單中,每個表單元素都鏈接到一個指令上,該指令負責管理其內部表單模型。下圖使用相同的 "喜歡的顏色" 示例來演示當輸入字段的值的變更來自視圖和來自模板時,數據如何流動。
下面這些步驟列出了當輸入框的值從 Red 變成 Blue 時 "從視圖到模型" 的數據流概況。
-
最終用戶在輸入框元素中敲 "Blue"。
-
該輸入框元素會發出一個 "input" 事件,帶着值 "Blue"。
-
附着在該輸入框上的控件值訪問器會觸發
FormControl
實例上的setValue()
方法。 -
FormControl
實例通過valueChanges
這個可觀察對象發出新值。 -
valueChanges
的任何訂閱者都會收到新值。 -
控件值訪問器
ControlValueAccessory
還會調用NgModel.viewToModelUpdate()
方法,它會發出一個ngModelChange
事件。 -
由於該組件模板雙向數據綁定到了
favoriteColor
,組件中的favoriteColor
屬性就會修改爲ngModelChange
事件所發出的值("Blue")。
下面這些步驟列出了當 favoriteColor
從 Blue 變爲 Red 時,"從模型到視圖" 的數據流概況。
-
組件中修改了
favoriteColor
的值。 -
變更檢測開始。
-
在變更檢測期間,由於這些輸入框之一的值發生了變化,Angular 就會調用
NgModel
指令上的ngOnChanges
生命週期鉤子。 -
ngOnChanges()
方法會把一個異步任務排入隊列,以設置內部FormControl
實例的值。 -
變更檢測完成。
-
在下一個檢測週期,用來爲
FormControl
實例賦值的任務就會執行。 -
FormControl
實例通過可觀察對象valueChanges
發出最新值。 -
valueChanges
的任何訂閱者都會收到這個新值。 -
控件值訪問器
ControlValueAccessor
會使用favoriteColor
的最新值來修改表單的輸入框元素。
表單驗證
驗證是管理任何表單時必備的一部分。無論你是要檢查必填項,還是查詢外部 API 來檢查用戶名是否已存在,Angular 都會提供一組內置的驗證器,以及創建自定義驗證器所需的能力。
-
響應式表單把自定義驗證器定義成函數,它以要驗證的控件作爲參數。
-
模板驅動表單和模板指令緊密相關,並且必須提供包裝了驗證函數的自定義驗證器指令。
實踐
在使用響應式表單的時候,報錯如下:
因爲在理論學習的過程中瞭解到了,對於響應式表單而言,爲表單控件添加 formControl
綁定,formControl
是由 ReactiveFormsModule
中的 FormControlDirective
提供的。
並且官網中明確說明了:要使用響應式表單,就要從 @angular/forms
包中導入 ReactiveFormsModule
並把它添加到你的 NgModule 的 imports
數組中。
因此,需要在在app.module.ts中引入即可。