在Angular表单控件中使用数组时如何将字段设为必填并校验空值
Angular FormArray 字段必填校验实现方案
该问题的核心原因是校验规则绑定对象错误,不要直接给FormArray本身加必填校验,而是要给FormArray内部每个动态新增的FormGroup的子控件绑定必填校验,具体实现步骤如下:
1. 定义带校验的表单项结构
初始化表单时,单独封装数组单条数据的生成方法,给每个子字段绑定Validators.required必填校验:
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; constructor(private fb: FormBuilder) {} // 生成单个带必填校验的数组项 createArrayItem(): FormGroup { return this.fb.group({ field1: ['', Validators.required], field2: ['', Validators.required], field3: ['', Validators.required], field4: ['', Validators.required] }) } // 初始化主表单 ngOnInit() { this.mainForm = this.fb.group({ // 若要求数组至少保留1项,可给FormArray加Validators.minLength(1)校验 arrayA: this.fb.array([this.createArrayItem()], Validators.minLength(1)), arrayB: this.fb.array([this.createArrayItem()], Validators.minLength(1)) }) } // 点击+号新增数组项逻辑 addArrayItem(arrayKey: 'arrayA'|'arrayB') { const targetArray = this.mainForm.get(arrayKey) as FormArray; targetArray.push(this.createArrayItem()); }
2. 全局校验逻辑实现
提交表单时直接使用表单自带的valid属性判断即可,Angular会自动递归校验所有子控件的有效性,不需要自行遍历判断空值:
submitForm() { if (this.mainForm.invalid) { // 把所有未通过校验的控件标记为已触碰,触发页面错误提示 Object.keys(this.mainForm.controls).forEach(arrayKey => { const arrayControl = this.mainForm.get(arrayKey) as FormArray; arrayControl.controls.forEach(itemGroup => { Object.keys(itemGroup.controls).forEach(fieldKey => { itemGroup.get(fieldKey)?.markAsTouched(); }) }) }) return; } // 校验通过后执行业务逻辑 const validFormData = this.mainForm.value; console.log('有效表单数据', validFormData); }
3. 模板错误提示绑定
模板中给每个子字段绑定必填错误提示即可:
<form [formGroup]="mainForm" (ngSubmit)="submitForm()"> <!-- 第一个数组区域 --> <div formArrayName="arrayA"> <h3>数组A</h3> <div *ngFor="let item of arrayA.controls; let index = index" [formGroupName]="index"> <input formControlName="field1" placeholder="字段1"> <span *ngIf="item.get('field1')?.touched && item.get('field1')?.hasError('required')" class="error"> 此字段为必填项 </span> <!-- 剩余3个字段的输入框和错误提示同理 --> </div> <button type="button" (click)="addArrayItem('arrayA')">+ 新增项</button> </div> <!-- 第二个数组区域结构和数组A一致 --> <div formArrayName="arrayB"> <!-- 省略重复结构 --> <button type="button" (click)="addArrayItem('arrayB')">+ 新增项</button> </div> <button type="submit">提交表单</button> </form>
异常排查
如果仍提示存在空索引,检查两个配置:
- 新增项时是否调用了封装的
createArrayItem方法生成带校验的FormGroup,而非手动push无校验规则的空FormGroup - 是否误将FormArray的原始值长度作为校验依据,未填写的字段会是空字符串,触发对应子控件的required校验,主表单的
valid属性会自动返回false,无需额外判断空值
内容的提问来源于stack exchange,提问作者Aman Chitransh
相关产品推荐
相关产品推荐

