angular 實現同步驗證器跨欄位驗證
需求:設定成績佔比時,如果總佔比不是100%,則無法通過驗證。
分析:需求很簡單,只需要寫一個驗證器即可,由於不需要訪問後臺,且驗證器與三個欄位有關,所以是同步跨欄位驗證。
實現驗證器
首先,去官網上找示例程式碼:
export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => { const name = control.get('name'); const alterEgo = control.get('alterEgo'); return name && alterEgo && name.value === alterEgo.value ? { 'identityRevealed': true } : null; };
解釋:這個身份驗證器實現了 ValidatorFn 介面。它接收一個 Angular 表單控制元件物件作為引數,當表單有效時,它返回一個 null,否則返回 ValidationErrors 物件。
從上可知,所謂跨欄位,就是從驗證表單單個控制元件formControl變成了驗證整個表單formGroup了,而formGroup的每個欄位就是formControl。
明白了這個原理,就是根據需求進行改寫:
// 判斷總佔比是否等於100 export const scoreWeightSumValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => { const sumLegal = formGroup.get('finalScoreWeight') .value + formGroup.get('middleScoreWeight') .value + formGroup.get('usualScoreWeight') .value === 100; // 如果是,返回一個 null,否則返回 ValidationErrors 物件。 return sumLegal ? null : {'scoreWeightSum': true}; };
到此,驗證器已經寫完。
新增到響應式表單
給要驗證的 FormGroup 新增驗證器,就要在建立時把一個新的驗證器傳給它的第二個引數。
ngOnInit(): void { this.scoreSettingAddFrom = this.fb.group({ finalScoreWeight: [null, [Validators.required, scoreWeightValidator]], fullScore: [null, [Validators.required]], middleScoreWeight: [null, [Validators.required, scoreWeightValidator]], name: [null, [Validators.required]], passScore: [null, [Validators.required]], priority: [null, [Validators.required]], usualScoreWeight: [null, [Validators.required, scoreWeightValidator]], }, {validators: scoreWeightSumValidator}); }
新增錯誤提示資訊
我使用的是ng-zorro框架,當三個成績佔比均輸入時,觸發驗證
<nz-form-item nz-row> <nz-form-control nzValidateStatus="error" nzSpan="12" nzOffset="6"> <nz-form-explain *ngIf="scoreSettingAddFrom.errors?.scoreWeightSum && scoreSettingAddFrom.get('middleScoreWeight').dirty && scoreSettingAddFrom.get('finalScoreWeight').dirty && scoreSettingAddFrom.get('usualScoreWeight').dirty">成績總佔比需等於100%! </nz-form-explain> </nz-form-control> </nz-form-item>
效果:
總結
總的來說這個驗證器實現起來不算很難,就是讀懂官方文件,然後根據自己的需求進行改寫。
參考文件: angular表單驗證 跨欄位驗證