iT邦幫忙

0

[Angular] Forms - Introduction to form in Angular

前言

在前端領域中,使用表單處理用戶輸入是常見的操作,可以使用表格讓使用者登錄、輸入信息以及其他數據輸入的任務,Angular提供了兩種通過表單處理用戶輸入的方法:reactivetemplate,這兩種方法,此篇章將會介紹他們之間的差異與用途。

Choosing an approach

reactive與template以不同的方式處理表單訊息,他們擁有各自的優劣勢:

  • Reactive:提供對地層表單物件直接且顯性的訪問,他的可擴充性、可重用性、可測試性都比template更高。
  • template:依賴template中的指令來建立和操作底層物件,很容易新增到應用中,適合用在非常基本的表單需求與邏輯。

Key differences

... Reactive template
建立表單模型 在class中建立 在template中建立
資料模型 不可變 可變
可預測性 同步 非同步
驗證 function 指令

Setting up the form model

Reactive與Template都會追蹤使用者互動的表單輸入元素元件模型中的表單資料的變更,他們共用同一套底層模塊,不同的是他們在建立和管理表單的方面不同。

Common form foundation classes

reactive和template都透過以下幾本的class建立:

  • FormControl:追蹤單個表單元件的值和驗證狀態。
  • FormGroup:追蹤一個表單控制元件集合的值和狀態。
  • FormArray:追蹤一個陣列中表單控制元件的值和狀態。
  • ControlValueAccessor:建立連接Angular FromControl與DOM的橋樑。

Setup in reactice forms

若要使用reactive forms,可以在Component中定義form model,[formControl]會使用internal value accessor將畫面中特定表單元素與FormControl連接起來。

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]指令將畫面中的input元件與Component中的FormControl物件連接起來,換句話說當使用者在畫面上的input中輸入值,會透過[formControl]將使用者輸入的值傳遞給Conponent中的FormControl物件。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767nZNWWulKXR.png
(圖片來源:Angular

Setup in template-driven forms

由於Template forms的表單形式是隱性的,所以所以需要透過NgModel來建立並管理FormControl。

import { Component } from '@angular/core';

@Component({
  selector: 'app-template-favorite-color',
  template: `
    Favorite Color: <input type="text" [(ngModel)]="favoriteColor">
  `
})
export class FavoriteColorComponent {
  favoriteColor = '';
}

在template form中,透過NgModel將使用者輸入的數值連接到Component中的FormControl。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767I5h14STnQc.png
(圖片來源:Angular


Data flow in forms

Angular必須在我們使用form的時候將畫面與Componet中的model保持同步,舉例來說當使用者在畫面中更改了表單中的資料時,新的值必須要立馬反映在model中,同樣的當model中的邏輯改變時,其結果也需要立即的反應在畫面中,Reactive與Template在處理使用者或程式更改的方式有所不同。

Data flow in reactive forms

在reactive forms中,畫面裡的每一個表單元素都直接的連接到FormControl,畫面與model的之間的數據更新是同步的,下圖表示當畫面更改元件中的數值時數據是如何流動到FromControl中。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767nM0MOJMxp1.png
(圖片來源:Angular

  1. 使用者在畫面中的表單輸入新的值。
  2. 畫面中的表單元件發出帶有最新數值的輸入事件
  3. 畫面中表單元件的Control Value Accessor會監聽這個表單元件上的事件,並立即將新的值傳遞給Component中的FormControl。
  4. Component中的FormControl會透過valueChange這個可觀察物件發送這個新的值給valueChange的訂閱者。
  5. 所有valueChange的訂閱者收到使用者輸入的新值。

下圖是介紹FormControl的值被更改後,如何將更改的值反映到畫面中。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767ycks8Ex7Xn.png
(圖片來源:Angular

  1. 呼叫favoriteColorControl.setValue()來更新FormControl的值。
  2. FormControl透過valueChanges發出新值。
  3. valueChanges的訂閱者會收到新值(畫面中的input元件)。
  4. 畫面input元件更新收到的新值。

Data flow in template-driven forms

在template forms中的每個表單元件都會連接到內部管理表單模型的指令。

下圖說明了當更改畫面元件後,更新的數值是如何流向model。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767iwvCFPMhTN.png
(圖片來源:Angular

  1. 使用者輸入新值(blue)。
  2. input元件發出帶有新值(blue)的輸入事件。
  3. input元件觸發FormContorl的setValue()方法來更新FormControl的值。
  4. FormControl透過valueChanges發出新值。
  5. valueChanges的訂閱者收到新值。
  6. Control Value Accessory呼叫Model.viewModelUpdate(),發出一個ngModelChange事件。
  7. ngModelChange事件會修改Component中雙向綁定的屬性的值(this.favoriteColor)

下圖說明當修改Component中的this.favoriteColor後,畫面中的input表單是如何更新新值。
https://ithelp.ithome.com.tw/upload/images/20201104/20124767KbAXvasFXX.png
(圖片來源:Angular

  1. Component中的this.favoriteColor更改了值(red)。
    --------- 變更檢測開始 ---------
  2. Angular呼叫NgModel上的ngOnChanges方法。
  3. ngOnChange會將一個非同步更改FormControl值的任務放入佇列中。
    --------- 變更檢測結束 ---------
  4. FormControl更新任務完成。
  5. FormControl透過valueChanges發出新值。
  6. valueChanges的訂閱者收到新值。
  7. Control Value Accessor更新畫面input元件中的值。

Mutability of the data model

  • Reactive:reactive forms透過不能改變的數據結構來保持數據行的單一化,當每一次觸發更新時,FormControl都會return一個新的數據模型而不是更新現有的數據模型,這使變更檢測更有效率,因為只需要在唯一性更改(物件參考發生變化)時進行更新。
  • Template:template forms依賴雙向資料綁定,由於使用雙向資料綁定時沒有用來對資料模型進行追蹤的唯一性更改,因此變更檢測在需要確定何時更新時效率較低。

參考文獻:Angular


尚未有邦友留言

立即登入留言