Angular 11响应式表单如何实现指定字段组至少一项必填的自定义校验
Angular 11 响应式表单自定义校验器实现
1. 编写自定义校验函数
直接在你的组件文件或者公共校验工具文件中添加如下代码:
import { AbstractControl, ValidationErrors, ValidatorFn, FormGroup } from '@angular/forms'; // 自定义组校验:指定字段列表中至少存在一个非空值 const atLeastOneRequired = (checkFields: string[]): ValidatorFn => { return (control: AbstractControl): ValidationErrors | null => { const form = control as FormGroup; // 遍历检查字段是否有值,兼容空字符串、null、undefined场景 const hasValidValue = checkFields.some(field => { const controlVal = form.get(field)?.value; return controlVal !== null && controlVal !== undefined && controlVal !== ''; }); return hasValidValue ? null : { atLeastOneEmpty: true }; }; }; // 可选补充:如果需要校验结束日期不能早于开始日期,可以添加这个校验器 const dateRangeValidator = (control: AbstractControl): ValidationErrors | null => { const start = control.get('startDate')?.value; const end = control.get('endDate')?.value; if (start && end && new Date(end) < new Date(start)) { return { dateRangeInvalid: true }; } return null; };
2. 修改表单初始化配置
你原来的开始、结束日期已经配置了单字段必填校验,本身就会控制两个日期都填才合法,只需要在FormGroup级校验里加上至少一个字段的校验规则即可:
this.myForm = new FormGroup({ startDate: new FormControl('', Validators.required), endDate: new FormControl('', Validators.required), phoneNumber: new FormControl(''), address: new FormControl(''), author: new FormControl(), userID: new FormControl(''), company: new FormControl('') }, { // 传入组校验规则,多个校验器用数组包裹 validators: [ dateRangeValidator, // 不需要日期范围校验可以删掉这行 atLeastOneRequired(['phoneNumber', 'address', 'author', 'userID', 'company']) ] });
3. 模板错误提示参考
可以根据需要在页面上展示错误提示:
<!-- 多字段至少填一项提示 --> <span *ngIf="myForm.hasError('atLeastOneEmpty')" class="error"> 手机号码、地址、作者、用户ID、公司至少填写一项 </span> <!-- 日期范围错误提示 --> <span *ngIf="myForm.hasError('dateRangeInvalid')" class="error"> 结束日期不能早于开始日期 </span>
逻辑说明
两个日期只要有一个没填,单字段的required校验会触发,表单整体invalid;五个选填字段都为空时,组校验触发,表单整体invalid;只有两个条件同时满足时,myForm.valid才会返回true,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者USERxxx1
相关产品推荐
相关产品推荐

