如何验证FormArray中FormGroup内的控件?以numeroCelular为例
解决FormArray内FormGroup控件的验证问题
看起来你在处理Angular表单中嵌套在FormArray里的FormGroup控件验证时遇到了问题,主要是numeroCelular字段的必填验证提示无法正确显示。咱们一步步来修正:
首先,修正组件类(component.ts)里的错误
你的errorNumeroCelular方法犯了两个关键错误:
- 把
telefonos这个FormArray当成了FormGroup来处理 - 模板调用时没有传入索引
i,导致无法定位到对应的FormGroup
咱们先给FormArray加个便捷的getter(推荐做法,代码更清晰),然后修正错误判断方法:
import { FormArray, FormGroup } from '@angular/forms'; // ... 其他代码 ... this.formContacto = this.fb.group({ telefonos: this.fb.array([ this.fb.group({ tipo: [''], numeroCelular: ['', Validators.required], whatsapp: [], codigoCiudad: [], numeroFijo: [], }) ]) }); // 新增:获取telefonos FormArray的便捷getter get telefonos(): FormArray { return this.formContacto.get('telefonos') as FormArray; } // 修正错误提示方法 errorNumeroCelular(i: number): string { // 先拿到对应索引的FormGroup const telefonoGroup = this.telefonos.at(i) as FormGroup; // 获取numeroCelular控件 const numeroCelularControl = telefonoGroup.get('numeroCelular'); // 推荐加上touched/dirty判断,避免页面一开始就显示错误 if (numeroCelularControl?.hasError('required') && numeroCelularControl.touched) { return 'Ingrese un número de celular'; } return ''; }
然后修正模板(component.html)
要注意两个点:
- 确保你的
mat-form-field是在FormGroup的上下文中(也就是循环FormArray时,要指定formGroupName) - 调用
errorNumeroCelular时必须传入当前的索引i
假设你是用*ngFor循环渲染telefonos数组,完整的模板代码应该是这样:
<!-- 外层form要绑定formContacto --> <form [formGroup]="formContacto"> <!-- 循环telefonos FormArray --> <div formArrayName="telefonos"> <div *ngFor="let telefono of telefonos.controls; let i = index" [formGroupName]="i"> <mat-form-field appearance="standard"> <mat-label>Número celular</mat-label> <input matInput formControlName="numeroCelular"> <!-- 传入索引i,并判断错误是否存在 --> <mat-error *ngIf="errorNumeroCelular(i)">{{errorNumeroCelular(i)}}</mat-error> </mat-form-field> </div> </div> </form>
额外优化建议
为了避免重复调用errorNumeroCelular方法(模板里每次变更检测都会调用两次),可以在模板里直接访问控件状态,比如:
<mat-error *ngIf="telefonos.at(i).get('numeroCelular')?.hasError('required') && telefonos.at(i).get('numeroCelular')?.touched"> Ingrese un número de celular </mat-error>
这样可以省去组件类里的errorNumeroCelular方法,代码更简洁~
内容的提问来源于stack exchange,提问作者Paco Zevallos
相关产品推荐
相关产品推荐

