Angular如何在跨欄位驗證器中直接呼叫其它獨立的驗證器

myskies發表於2022-03-24

本文 DEMO 地址:原始碼最終效果

angular中關於表單動態驗證的一種新思路一文中我們給出了Angular專案進行欄位校驗的三種方法。本文我們將重點圍繞第一種方法展開討論。

假設有如下應用:
image.png

該應用的功能是對輸入的數值的奇偶數進行判斷,如果滿足條件,則啟用Submit按鈕,否則不啟用。

跨欄位驗證

由於對輸入數值的校驗是根據輸入型別來區分的,所以這裡我們需要一個跨輸入型別輸入數值的驗證器:

  ngOnInit(): void {
    this.formGroup.setValidators((formGroup) => {
      formGroup = formGroup as FormGroup;
      const type = formGroup.get('type').value as number;
      if (type === 0) {
        // 驗證是否是偶數 1️⃣
      } else {
        // 驗證是否為奇數 1️⃣
      }
    });
  }

雖然我們可以在1️⃣處直接寫入驗證器的邏輯,但從分工的角度上來講,這往往是最壞的一種的方案。
為此,我們同時準備了驗證器:


/**
 * 數字校驗器
 */
export class NumberValidator {
  /**
   * 偶數校驗器
   */
  static isEven(control: AbstractControl): ValidationErrors | null {
    const value = +control.value as number;
    if (Number.isInteger(value) && value % 2 === 0) {
      return null;
    } else {
      return { isEven: '輸入的數字不是偶數' };
    }
  }

  /**
   * 奇數校驗器
   */
  static isOdd(control: AbstractControl): ValidationErrors | null {
    const value = +control.value as number;
    if (Number.isInteger(value) && value % 2 === 1) {
      return null;
    } else {
      return { isOdd: '輸入的數字不是奇數' };
    }
  }
}

使用獨立的驗證器

有了獨立的驗證器後,我們可以使用類似如下的程式碼,直接在跨欄位校驗器中進行呼叫:

  ngOnInit(): void {
    this.formGroup.setValidators((formGroup) => {
      formGroup = formGroup as FormGroup;
      const type = formGroup.get('type').value as number;
      if (type === 0) {
        return NumberValidator.isEven(formGroup.get('value')); ?
      } else {
        return NumberValidator.isOdd(formGroup.get('value')); ?
      }
    });
  }

是的,在呼叫的時候將需要驗證的FormControl傳入即可。

如果我們的跨欄位驗證器需要同時對多個欄位進行校驗,則還可以這樣:

        const result = {
          ...Validators.required(formGroup.get(this.formKeys.image)),
          ...Validators.required(formGroup.get(this.formKeys.imageLeftTopPoint)),
          ...Validators.required(formGroup.get(this.formKeys.imageRightBottomPoint)),
          ...MapPointValidator.isPoint(formGroup.get(this.formKeys.imageLeftTopPoint)),
          ...MapPointValidator.isPoint(formGroup.get(this.formKeys.imageRightBottomPoint))
        }

        return Object.keys(result).length === 0 ? null : result; ?

? 處對返回的錯誤資訊進行判斷,如果長度為0,則說明返回了{},直接返回null,否則返回多個驗證器拼接後的錯誤資訊。

如果你想看到具體的程式碼及效果,請點選:示例程式碼最終效果

相關文章