Angular 響應式表單 基礎例子

一、案例需求

表單提交,表單所有校驗成功才能提交,當表單校驗錯誤,表單邊框變紅,同時有錯誤提示信息,有重置功能javascript

二、代碼分析

本案例中使用了響應式表單,響應式表單在表單的校驗方面很是方便java

2.一、註冊 ReactiveFormsModule

要使用響應式表單,就要從 @angular/forms 包中導入 ReactiveFormsModule 並把它添加到你的 NgModule 的 imports 數組中。git

app.module.tsgithub

imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule
  ]

2.二、使用 FormBuilder 來生成表單控件

當須要與多個表單打交道時,手動建立多個表單控件實例會很是繁瑣。FormBuilder 服務提供了一些便捷方法來生成表單控件。FormBuilder 在幕後也使用一樣的方式來建立和返回這些實例,只是用起來更簡單。數組

  • 注入 FormBuilder 服務
constructor(
    private fb: FormBuilder
  ) { }
  • 生成表單控件

FormBuilder 提供了一個語法糖,以簡化 FormControl、FormGroup 或 FormArray 實例的建立過程。它會減小構建複雜表單時所需的樣板代碼的數量(new FormControl)。app

formGroup: FormGroup;

this.formGroup = this.fb.group({
      name: '',
      age: '',
      sex: ''
    });

2.三、FormGroupDirective

formGroup 是一個輸入指令,它接受一個 formGroup 實例,它會使用這個 formGroup 實例去匹配 FormControl、FormGroup、FormArray 實例,因此模版中的 formControlName 必須和 formGroup 中的 name 匹配。ui

<form [formGroup]="formGroup" (ngSubmit)="submit()" novalidate>
  <div class="form-group">
    <label>姓名:</label>
    <input type="text"
      formControlName="name">
      <p>{{nameErrorMessage}}</p>
  </div>
</form>

2.四、表單狀態

每一個表單控件都有本身的狀態,共五個狀態屬性,都是布爾值。this

  • valid 表單值是否有效
  • pristine 表單值是否未改變
  • dirty 表單值是否已改變
  • touched 表單是否已被訪問過
  • untouched 表單是否未被訪問過

以輸入姓名的表單爲例,只驗證該表單的必填項時。表單先獲取焦點而且輸入姓名,最後移除焦點,每一步表單的狀態以下:code

初始狀態
狀態
valid false
pristine true
dirty false
touched false
untouched true
輸入狀態
狀態
valid true
pristine false
dirty true
touched false
untouched true
失去焦點後狀態
狀態
valid true
pristine false
dirty true
touched true
untouched true

2.五、表單校驗

表單驗證用於驗證用戶的輸入,以確保其完整和正確。Angular內置的了一些校驗器,如 Validators.required, Validators.maxlength,Validators.minlength, Validators.pattern,可是不能自定義錯誤提示信息,因此實用性不強,知足不了業務場景的需求,因而咱們能夠自定義表單校驗器。component

自定義表單校驗器

name-validator.ts

import { AbstractControl, ValidatorFn } from '@angular/forms';

export function nameValidator(): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } => {

    if (!control.value) {
      return { message: '請輸入必選項' };
    }

    if (control.value.length > 10) {
      return { message: '名稱大於10位了' };
    }

    return null;

  };
}

使用自定義驗證器

app.component.ts

this.formGroup = this.fb.group({
      name: ['', nameValidator()],
      age: ['', ageValidator()],
      sex: ['', sexValidator()]
    });

顯示錯誤提示信息

當頁面初始化的時候不該該顯示錯誤信息,也就是表單touched爲true

// Error
private errorMessage(name): string {
    const control = this.formGroup.controls[name];
    return (control.touched && control.invalid) ? control.errors.message : '';
  }

然而touched只有失去焦點才爲true,在輸入的時候一直爲false。致使在輸入的時候,表單校驗錯誤,卻顯示不了錯誤信息。所以須要再次判斷 dirty 狀態,只要表單值改變,則爲false

private errorMessage(name): string {
    const control = this.formGroup.controls[name];
    return ((control.touched || control.dirty) && control.invalid) ? control.errors.message : '';
  }

2.六、markAsTouched

未對錶單操做時,點擊提交按鈕時,則模擬表單被touched,顯示提示信息

markFormGroupTouched(formGroup: FormGroup) {
    (<any>Object).values(formGroup.controls).forEach(item => {
      if (item.controls) {
        this.markFormGroupTouched(item);
      } else {
        item.markAsTouched();
      }
    });
  }
相關文章
相關標籤/搜索