在angular中關於表單動態驗證的一種新思路一文中我們給出了Angular專案進行欄位校驗的三種方法。本文我們將重點圍繞第一種方法展開討論。
假設有如下應用:
該應用的功能是對輸入的數值的奇偶數進行判斷,如果滿足條件,則啟用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
,否則返回多個驗證器拼接後的錯誤資訊。