Angular 4嵌套FormArray/FormGroup数据库回填值报错排查
排查Angular嵌套FormArray回填失败的问题
你遇到的Cannot find control with path: 'segmentRows3 -> 0 '错误和personRows3无法回填的问题,主要是表单控件构建逻辑错误、大小写不匹配以及模板遍历数据源错误这几个核心原因导致的,下面一步步帮你修复:
1. 修复getPerson函数的关键问题
你的getPerson函数存在三个致命问题:
- 没有返回构建好的
FormArray,导致personRows3控件根本没被添加到表单组中 - 提前尝试从表单中获取还未创建的
personRows3控件(此时segment的FormGroup还没被push到segmentRows3数组中) - 控件名大小写不匹配:TS里写的是
PersonRows3(大写P),但模板里用的是personRows3(小写p)
修正后的getPerson函数应该直接根据数据源构建并返回FormArray:
getPerson(s_i: any[], index: number) { const personData = s_i[index].personRows3; // 遍历person数据,批量构建FormGroup后转为FormArray return this.fb.array( personData.map(person => this.fb.group({ personR3: person.personR3, personI3: person.personI3 })) ); }
2. 修正segmentRows3的构建逻辑
在构建segmentRows3的时候,要确保控件名和模板完全一致(改用小写的personRows3),同时先初始化表单结构:
// 先初始化表单根结构,包含segmentRows3 FormArray this.myEditSummaryForm = this.fb.group({ segmentRows3: this.fb.array([]) }); const segmentRows3 = this.myEditSummaryForm.get('segmentRows3') as FormArray; // 遍历seg_inf构建每个segment的FormGroup for (let i = 0, len = this.seg_inf.length; i < len; i++) { segmentRows3.push( this.fb.group({ segmentTime3: this.seg_inf[i].segmentTime3, segmentId3: i + 1, topic: this.seg_inf[i].topic, personRows3: this.getPerson(this.seg_inf, i) // 控件名统一为小写personRows3 }) ); }
3. 修正模板中personRows3的遍历逻辑
模板中不能直接遍历数据源seg.personRows3,应该遍历表单控件数组,同时添加一个辅助方法来快速获取对应segment下的personRows3 FormArray:
先在TS中添加辅助方法:
getPersonArray(segmentIndex: number): FormArray { return this.myEditSummaryForm.get(`segmentRows3.${segmentIndex}.personRows3`) as FormArray; }
修正后的HTML片段:
<div formArrayName="personRows3"> <!-- 改为遍历表单控件数组,而非原始数据源 --> <div *ngFor="let per of getPersonArray(i).controls; let j=index"> <div class="form-group" [formGroupName]="j"> #{{j+1}} <label for="personR3">Segment type <input formControlName="personR3" [typeahead]="personRole" type="text" id="personR3" class="form-control"> </label> <label for="personI3">Person name <input formControlName="personI3" [typeahead]="states" type="text" id="personI3" class="form-control"> </label> <!-- 修正删除按钮的判断条件:判断当前segment下的person数量 --> <label><span *ngIf="getPersonArray(i).length > 1" (click)="deletePerson(i,j)" class="btn btn-warning">Remove</span></label> </div> </div> </div>
4. 清理冗余干扰项
移除输入框上的value="{{i+1}}",因为FormControl会自动回填值,手动设置value会干扰表单控件的双向绑定逻辑。
经过这些修正后,嵌套的FormArray就能正确回填数据库数据,也不会再出现找不到控件路径的错误了。
内容的提问来源于stack exchange,提问作者mamesaye
相关产品推荐
相关产品推荐

