Angular响应式表单如何校验FormArray至少选中一个复选框
Angular动态表单「至少选中一个复选框」校验实现方案
1. 编写自定义聚合校验器
Angular内置校验器不支持FormArray子项的跨字段聚合校验,先新建专用校验函数,遍历检查FormArray中是否存在isAnswer为true的项:
import { AbstractControl, ValidatorFn, FormArray } from '@angular/forms'; /** * FormArray校验规则:至少有一个子项的isAnswer字段为true */ export function atLeastOneAnswerChecked(): ValidatorFn { return (control: AbstractControl): {[key: string]: boolean} | null => { const answerArray = control as FormArray; // 遍历检查是否存在选中项 const hasChecked = answerArray.controls.some(item => { return item.get('isAnswer')?.value === true; }); return hasChecked ? null : { required: true }; }; }
2. 给answers FormArray绑定校验规则
修改表单初始化代码,创建answers FormArray时把自定义校验器作为第二个参数传入:
ngOnInit() { this.questionForm = this._formBuilder.group({ label: ['', Validators.required], // 绑定自定义校验器到FormArray answers: this._formBuilder.array([], atLeastOneAnswerChecked()), }); this.addOption(); }
注意:后续新增/删除表单子项、切换复选框状态时,FormArray会自动重新执行该校验规则,无需额外手动触发。
3. 修正模板错误提示逻辑
原有模板的错误提示缺少提交状态判断,和其他字段的校验显示逻辑保持一致即可,修改对应代码块:
<div class="invalid-feedback" *ngIf=" formSubmitAttempt && questionForm.get('answers')?.errors && questionForm.get('answers')?.errors?.required " > 至少需要选中一个复选框作为答案 </div>
如果需要切换复选框时实时显示错误(无需等提交),可以给复选框控件加变更事件触发校验更新:
<input class="form-check-input" type="checkbox" formControlName="isAnswer" (change)="questionForm.get('answers')?.updateValueAndValidity()" />
4. 补充提交时的统一校验逻辑
在提交方法中统一标记表单提交状态、触发全量校验,避免漏判:
onSubmit(event: Event) { event.preventDefault(); this.formSubmitAttempt = true; // 标记所有控件为已触碰状态,触发错误提示显示 this.questionForm.markAllAsTouched(); if (this.questionForm.invalid) { return; } // 校验通过后的业务提交逻辑 console.log('表单合法,提交数据:', this.questionForm.value); }
内容的提问来源于stack exchange,提问作者Rasik
相关产品推荐
相关产品推荐

