You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'

问题原因

核心问题有两个:

  1. 未为FormArray中的每个FormGroup设置formGroupName绑定,Angular无法识别输入框所属的具体组;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:56:08