需求:设置成绩占比时,若是总占比不是100%,则没法经过验证。框架
分析:需求很简单,只须要写一个验证器便可,因为不须要访问后台,且验证器与三个字段有关,因此是同步跨字段验证。ide
首先,去官网上找示例代码:ui
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 对象。this
从上可知,所谓跨字段,就是从验证表单单个控件formControl变成了验证整个表单formGroup了,而formGroup的每一个字段就是formControl。spa
明白了这个原理,就是根据需求进行改写:code
// 判断总占比是否等于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}; };
到此,验证器已经写完。orm
给要验证的 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>
效果:ip
总的来讲这个验证器实现起来不算很难,就是读懂官方文档,而后根据本身的需求进行改写。
参考文档:angular表单验证 跨字段验证