Angular响应式表单报错Cannot find control with path: 'flights -> 3'如何解决
错误根因
你碰到的报错核心是两个问题:
- 仅操作了普通数组
flightChildAges,没有同步更新响应式表单中对应的flightChildAgeFormArray控件,Angular找不到对应索引的表单控件抛出路径错误 - 模板中没有正确嵌套
flightsFormGroup的层级,FormArray绑定方式错误
修复步骤
1. 调整component.ts逻辑
首先移除无用的普通数组flightChildAges,直接操作表单内置的FormArray,修改代码如下:
import { FormArray } from '@angular/forms'; // 先导入FormArray noOfChild = 0; noOfInfant = 0; flightInfantAges; // 新增getter快捷获取flightChildAge FormArray实例 get flightChildAgeArray(): FormArray { return this.form.get('flights.flightChildAge') as FormArray; } async onNoOfChild(event) { // 输入框值是字符串,转成数字避免比较异常 const target = Number(event.target.value); if (!isNaN(target) && target >= 0) { const diff = target - this.noOfChild; if (diff < 0) { // 数量减少,从末尾删除对应数量的FormControl for (let i = 0; i < Math.abs(diff); i++) { this.flightChildAgeArray.removeAt(this.flightChildAgeArray.length - 1); } } else if (diff > 0) { // 数量增加,新增对应数量的FormControl for (let i = 0; i < diff; i++) { this.flightChildAgeArray.push(this.fb.control(0)); } } this.noOfChild = target; } else { // 输入为空,清空所有控件 this.flightChildAgeArray.clear(); this.noOfChild = 0; } }
2. 修复html模板绑定
调整FormGroup层级和FormArray的绑定方式:
<!-- 外层必须先绑定flights这个FormGroup,否则表单路径不匹配 --> <div formGroupName="flights"> <div class="col-md-3"> <div class="form-group"> <label for="flightChild" class="label">航班随行儿童数量(2-17周岁)</label> <input type="number" min="0" max="9" nbInput fullWidth id="flightChild" placeholder="请输入儿童数量" formControlName="flightChild" (input)="onNoOfChild($event)"/> <!-- 推荐用input事件代替keyup,适配数值调整按钮的操作 --> </div> </div> <div class="col-md-6"> <!-- FormArray要用formArrayName绑定,不能用formControlName --> <div formArrayName="flightChildAge"> <div *ngFor="let control of flightChildAgeArray.controls; let i=index" > <label for="child-{{ i }}" class="label" >第{{i+1}}位儿童年龄:</label> <input nbInput fullWidth id="child-{{ i }}" type="number" formControlName="{{i}}" min="3" max="17" required> <!-- 不需要手动绑定value,响应式表单会自动同步 --> </div> </div> </div> </div>
3. 可选:初始化默认值
如果需要加载已有数据时自动生成对应数量的输入框,在resetForm或者数据加载的逻辑里补充FormArray初始化:
// 比如加载的flightChildAge默认值是[10,3,9],就遍历生成对应控件 const defaultAges = [10,3,9]; defaultAges.forEach(age => { this.flightChildAgeArray.push(this.fb.control(age)); }); this.noOfChild = defaultAges.length;
内容的提问来源于stack exchange,提问作者hanu
相关产品推荐
相关产品推荐

