Angular 5 FormArray报错:Cannot find control with path: 'fields -> 0 -> name'
解决Angular FormArray绑定错误:Cannot find control with path: 'fields -> 0 -> name'
这个错误的核心原因很明确:你在创建fields数组里的每个元素时,用了FormControl,但实际上每个field是包含name、type、value三个子控件的FormGroup,而模板里你用了formGroupName="{{i}}"来绑定分组,Angular自然找不到对应路径的控件啦。
第一步:修正TypeScript代码中FormArray的创建逻辑
把原来创建单个FormControl的代码改成创建FormGroup,每个分组里包含三个对应的FormControl。你可以直接用FormBuilder来简化这个过程:
// 替换原来的fieldscontrol创建逻辑 let fieldscontrol = new FormArray([]); template.fields.forEach(field => { // 这里改成FormGroup,每个字段对应一个FormControl let fieldGroup = this.formBuilder.group({ name: [field.name, Validators.required], type: [field.type, Validators.required], value: [field.value, Validators.required] }); fieldscontrol.push(fieldGroup); })
或者更简洁的写法,用map来生成数组:
const fieldscontrol = this.formBuilder.array( template.fields.map(field => this.formBuilder.group({ name: [field.name, Validators.required], type: [field.type, Validators.required], value: [field.value, Validators.required] }) ) );
另外,建议给组件加一个getter来获取fields数组,这样模板里的代码更清晰,也避免直接访问form.controls.fields.controls这种冗长的写法:
get fields(): FormArray { return this.form.get('fields') as FormArray; }
第二步:修正模板中的两处细节
- 把
*ngFor里的遍历对象改成我们刚才定义的getter:
<div *ngFor="let field of fields.controls; let i = index">
- 修正
[attr.id]的绑定,你之前写的name + i会把name当成变量,应该改成字符串拼接:
<input class="editor-field" [attr.id]="'name' + i" formControlName="name" /> <input class="editor-field" [attr.id]="'type' + i" formControlName="type" /> <input class="editor-field" [attr.id]="'value' + i" formControlName="value" />
完整修正后的关键代码片段
concept-template-edit.component.ts(核心部分)
ngOnInit() { this.sub = this.route.params.subscribe(params => { this.ctk = +params['ctk']; this.template = this.crs.getConceptTemplate(this.ctk).pipe( tap(template => { // 用FormBuilder创建fields的FormArray,每个元素是FormGroup const fieldscontrol = this.formBuilder.array( template.fields.map(field => this.formBuilder.group({ name: [field.name, Validators.required], type: [field.type, Validators.required], value: [field.value, Validators.required] }) ) ); this.form = this.formBuilder.group({ ctk: [template.ctk, Validators.required], tag: [template.tag, Validators.required], directaccess: [template.directaccess, Validators.required], fields: fieldscontrol, trigger: ['', Validators.required] }); console.log(this.form.value); }) ); }) } // 新增getter get fields(): FormArray { return this.form.get('fields') as FormArray; }
concept-template-edit.component.html(核心部分)
<div formArrayName="fields"> <div *ngFor="let field of fields.controls; let i = index"> <div class="form-group" formGroupName="{{i}}"> <input class="editor-field" [attr.id]="'name' + i" formControlName="name" /> <input class="editor-field" [attr.id]="'type' + i" formControlName="type" /> <input class="editor-field" [attr.id]="'value' + i" formControlName="value" /> </div> </div> </div>
这样修改后,Angular就能正确识别每个fields元素里的子控件路径,错误就会消失啦,表单也能正常绑定你的API返回数据。
内容的提问来源于stack exchange,提问作者Carlos Tavares
相关产品推荐
相关产品推荐

