Angular动态表单报错:无法找到streetAddress等控件求解决方案
解决Angular动态表单控件找不到的错误
问题场景
我在Angular中开发动态表单,HTML组件代码如下:
<div> <form [formGroup]="dynamicFormGroup" (ngSubmit)="onSubmit()"> <div class="form-row" *ngFor="let fields of AddressInfo.controls; let i = index" > <div class="form-group col-md-3" > <label for="password"><b>Street Address</b></label> <input type="text" class="form-control" placeholder="Street Address" name="SA" formControlName="streetAddress" /> </div> <div class="form-group col-md-3" > <label for="password"><b>City</b></label> <input type="text" class="form-control" placeholder="City" name="city" formControlName="city" /> </div> <div class="form-group col-md-3" > <label for="password"><b>State</b></label> <input type="text" class="form-control" placeholder="State" name="state" formControlName="state" /> </div> </div> <br/> <button type="submit" class="btn btn-primary">Submit</button> </form> <br/> <button type = "button" class="btn btn-primary" (click)="addNewAddress()" >Add New Address</button> </div> <h4>OUTPUT</h4> <div>{{output}}</div>
对应的.ts文件代码如下:
import { Component, OnInit } from '@angular/core'; import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-dynamic-form', templateUrl: './dynamic-form.component.html', styleUrls: ['./dynamic-form.component.css'], }) export class DynamicFormComponent implements OnInit { dynamicFormGroup!: FormGroup; output!: any; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.dynamicFormGroup = this.formBuilder.group({ address: new FormArray([this.createItem]), }); } addNewAddress(): void { (this.dynamicFormGroup.get('address') as FormArray).push(this.createItem); } get formControllers() { return this.dynamicFormGroup.controls; } get AddressInfo() { return this.formControllers['address'] as FormArray; } get createItem(): FormGroup { return this.formBuilder.group({ streetAddress: [], city: [], state: [], }); } onSubmit() { this.output = this.dynamicFormGroup.controls['address'].value; console.log(this.output); } }
运行时出现以下错误:
ERROR Error: Cannot find control with name: 'streetAddress'
ERROR Error: Cannot find control with name: 'city'
ERROR Error: Cannot find control with name: 'state'
问题原因
核心问题有两个:
- 未为FormArray中的每个FormGroup设置
formGroupName绑定,Angular无法识别输入框所属的具体组; createItem作为getter属性,直接引用会导致多次添加同一个FormGroup实例,引发数据同步问题。
解决方案
1. 修改HTML模板,添加formGroupName绑定
在循环的外层div上添加[formGroupName]="i",明确每个输入框对应的FormGroup:
<div> <form [formGroup]="dynamicFormGroup" (ngSubmit)="onSubmit()"> <!-- 新增formGroupName绑定,指定当前组的索引 --> <div class="form-row" *ngFor="let fields of AddressInfo.controls; let i = index" [formGroupName]="i"> <div class="form-group col-md-3" > <label for="password"><b>Street Address</b></label> <input type="text" class="form-control" placeholder="Street Address" name="SA" formControlName="streetAddress" /> </div> <div class="form-group col-md-3" > <label for="password"><b>City</b></label> <input type="text" class="form-control" placeholder="City" name="city" formControlName="city" /> </div> <div class="form-group col-md-3" > <label for="password"><b>State</b></label> <input type="text" class="form-control" placeholder="State" name="state" formControlName="state" /> </div> </div> <br/> <button type="submit" class="btn btn-primary">Submit</button> </form> <br/> <button type = "button" class="btn btn-primary" (click)="addNewAddress()" >Add New Address</button> </div> <h4>OUTPUT</h4> <div>{{output}}</div>
2. 优化TS代码,将createItem改为方法
避免重复引用同一个FormGroup实例,改为每次调用创建新实例:
import { Component, OnInit } from '@angular/core'; import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-dynamic-form', templateUrl: './dynamic-form.component.html', styleUrls: ['./dynamic-form.component.css'], }) export class DynamicFormComponent implements OnInit { dynamicFormGroup!: FormGroup; output!: any; constructor(private formBuilder: FormBuilder) {} ngOnInit() { // 调用方法创建新的FormGroup实例 this.dynamicFormGroup = this.formBuilder.group({ address: new FormArray([this.createItem()]), }); } addNewAddress(): void { // 调用方法创建新的FormGroup实例 (this.dynamicFormGroup.get('address') as FormArray).push(this.createItem()); } get formControllers() { return this.dynamicFormGroup.controls; } get AddressInfo() { return this.formControllers['address'] as FormArray; } // 改为普通方法,每次调用生成新的FormGroup createItem(): FormGroup { return this.formBuilder.group({ streetAddress: [], city: [], state: [], }); } onSubmit() { this.output = this.dynamicFormGroup.controls['address'].value; console.log(this.output); } }
说明
[formGroupName]="i"是解决控件找不到错误的核心:FormArray的每个元素都是独立FormGroup,必须通过索引指定当前组,Angular才能正确关联formControlName对应的控件;- 将
createItem改为方法:getter属性每次访问返回同一对象,多次添加会导致FormArray中多个项共享同一个FormGroup,改为方法可避免数据同步问题。
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

