Angular 表單簡介

angular-road

Angular 中有兩種表單:html

  • Template-driven Forms (相似於 AngularJS 1.x 中的表單 )typescript

  • Reactive Formssegmentfault

Template-driven 表單的特色

  • 使用方便數組

  • 適用於簡單的場景異步

  • 經過 [(ngModel)] 實現數據雙向綁定單元測試

  • 自動生成 Form Model (異步)測試

  • 最小化組件類的代碼ui

  • 不易於單元測試this

Reactive 表單的特色

  • 比較靈活spa

  • 適用於複雜的場景

  • 簡化了HTML模板的代碼,把驗證邏輯抽離到組件類中

  • 手動建立 Form Model (同步)

  • 方便的跟蹤表單控件值的變化

  • 易於動態添加表單控件

  • 易於單元測試

Template-driven vs Reactive 表單

Template-driven 表單

  • 模板

    • Form 元素

    • Input 元素

    • 數據綁定

    • 驗證規則 (屬性設置,如 required)

    • 錯誤消息

    • 自動建立對應的表單模型 (如 FormGroup、FormControl)

  • 組件類

    • 屬性綁定

    • 表單操做相關的方法,如表單提交 (submit)

  • 指令 (FormsModule)

    • ngForm

    • ngModel

    • ngModelGroup

Reactive 表單

  • 模板

    • Form 元素

    • Input 元素

    • Form 模型綁定

  • 組件類

    • Form 模型

    • 驗證規則

    • 錯誤消息

    • 數據模型相關屬性

    • 表單操做相關的方法,如表單提交 (submit)

  • 指令 (ReactiveFormsModule)

    • formGroup

    • formControl

    • formControlName

    • formGroupName

    • formArrayName

表單控件的狀態

  • Value Changed

    • pristine - 表單控件值未改變

    • dirty - 表單控件值已改變

  • Validity

    • valid - 表單控件有效

    • invalid - 表單控件無效

  • Visited

    • touched - 表單控件已被訪問過

    • untouched - 表單控件未被訪問過

HTML Form vs Template-driven Form vs Reactive Form

HTML Form

<form>
  <div>
    <label>
      <span>用戶名</span>
      <input
        type="text"
        name="userName"
        placeholder="請輸入用戶名">
    </label>
  </div>
  ...
  <button type="submit">註冊</button>
</form>

Template-driven Form

<form (ngSubmit)="save(signupForm)" #signupForm="ngForm">
  <div>
    <label>
      <span>用戶名</span>
      <input type="text" name="userName"
        placeholder="請輸入用戶名"
        required minlength="3"
        [(ngModel)]="user.userName"
        #userName="ngModel">
    </label>
    <div *ngIf="userName.touched && userName.errors?.required">
      用戶名是必填項
    </div>
    <div *ngIf="userName.touched && userName.errors?.minlength">
      用戶名的長度必須大於3
    </div>
  </div>
  ...
  <button type="submit">註冊</button>
</form>

Reactive Form

<form (ngSubmit)="save()" [formGroup]="signupForm">
  <div>
    <label>
      <span>用戶名</span>
      <input type="text" name="userName"
        placeholder="請輸入用戶名"
        formControlName="userName">
    </label>
    <div *ngIf="signupForm.get('userName').touched && 
        signupForm.get('userName').hasError('required')">
            用戶名是必填項
    </div>
    <div *ngIf="signupForm.get('userName').touched && 
        signupForm.get('userName').hasError('minlength')">
            用戶名的長度必須大於3
    </div>
  </div>
  ...
  <button type="submit" [disabled]="signupForm.invalid">註冊</button>
</form>

接下來咱們主要來介紹一下 Reactive Form 的一些相關基礎知識。

Reactive Form 簡介

使用 Reactive Form

要使用 Reactive Form 須要如下幾個步驟:

  • 導入 ReactiveFormsModule

import { ReactiveFormsModule } from "@angular/forms";
  • 在 NgModule 的 imports 屬性值對應的數組中,添加 ReactiveFormsModule

@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
})
export class AppModule { }
  • 綁定 form 元素的 formGroup 屬性

<form (ngSubmit)="save()" [formGroup]="signupForm"></form>
  • 關聯 input 元素對應的 FormControl 實例

<input type="text" name="userName" placeholder="請輸入用戶名" 
  formControlName="userName">

使用 FormGroup

  • 建立 FormGroup 屬性

  • 建立 FormGroup 實例

  • 建立每一個 FormControl 實例

signupForm: FormGroup; 

this.signupForm = new FormGroup({
  userName: new FormControl('', [Validators.required, Validators.minLength(3)]),
  email: new FormControl('', [Validators.required, Validators.email]),
  ...
});

使用 FormBuilder

要使用 FormBuilder 須要如下幾個步驟:

  • 導入 FormBuilder

  • 注入 FormBuilder 實例

  • 使用 FormBuilder 實例

FormBuilder 建立 Form Control 語法

  • 方式一

this.signupForm = this.fb.group({
  userName: 'semlinker',
  hasAddress: false
});
  • 方式二

this.signupForm = this.fb.group({
  userName: {value: 'semlinker', disabled: true}
  hasAddress: {value: true, disabled: false}
});
  • 方式三

this.signupForm = this.fb.group({
  userName: [''],
  hasAddress: [{value: true, disabled: false}]
})

進階資源

若想進一步閱讀更多表單相關的資料,請查看 Angular 4修仙目錄 - 表單章節

相關文章
相關標籤/搜索