我对动态输入字段有反应形式。我使用FormArray
生成了这些字段。现在,我正在尝试使用编辑屏幕上的数据预填充表单,但无法执行。我尝试使用setControl
方法填充此错误Cannot find control with path: 'books -> 0 -> name'
这些是我参考的来源
组件
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface ServerResponse {
books: any;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
formGroup: FormGroup;
books: FormArray;
constructor(
private http: HttpClient,
private formBuilder: FormBuilder,
) {
}
createForm() {
this.formGroup = this.formBuilder.group({
books: this.formBuilder.array([this.createBookForm()]),
});
}
createBookForm() {
return this.formBuilder.group({
name: [],
author: [],
});
}
addBook() {
this.books = this.formGroup.get('books') as FormArray;
this.books.push(this.createBookForm());
}
getData(): Observable<ServerResponse> {
return this.http.get<ServerResponse>('https://demo0331989.mockable.io/library/data/book');
}
populateData() {
this.getData().subscribe(data => {
this.formGroup.setControl('books', this.formBuilder.array(data.books || []));
});
}
ngOnInit() {
this.createForm();
this.populateData();
}
}
HTML
<form [formGroup]="formGroup">
<div formArrayName="books" *ngFor="let book of formGroup.get('books')['controls']; let i = index;">
<div class="row" [formGroupName]="i">
<input type="text" autocomplete="off" placeholder="*Name"
formControlName="name">
<input type="text" autocomplete="off" placeholder="*Author"
formControlName="author">
<button type="button" class="btn btn-success" (click)="addBook();">Add</button>
</div>
</div>
</form>
我也正在共享Stackblitz中的代码。样本/模拟data要预先填充。我不确定我在这里缺少什么!
答案 0 :(得分:0)
I did a fork from your stackblitz example,请看一看。当您要预先填充表单时,需要创建BookForm并将其传递给setControl,而不仅仅是数组。
答案 1 :(得分:0)
填充表单数组时,您需要使用填充的表单组填充它,因此它看起来像这样:
populateData() {
this.getData().subscribe(data => {
const books = this.formGroup.get('books') as FormArray; // get the array
books.clear(); // clear the array
data.books.forEach(b => { // iterate data
let fg = this.createBookForm(); // create the group
fg.reset(b); // fill the data
books.push(fg); // add to array
});
this.addBook(); // add blank form to end if desired
});
}
可能不需要也可能不需要清除表单部分/在末尾添加空白。
这是固定的闪电战:https://stackblitz.com/edit/angular-9ts4yv?file=src/app/app.component.ts
答案 2 :(得分:0)
免责声明,此答案与@ bryan60答案
是互补的我喜欢我的函数createBookForm具有参数“ data”,所以
createBookForm(data:any) {
data=data||{name:null,author:null}
return this.formBuilder.group({
name: data.name,
author: data.author,
});
}
这允许我们写
createBookForm(null) //create a FormGroup with name and author and values null
//or
createBookForm({name:"Linus Administration",author:"Roger"}) //the formgroup has values
我们的函数populateData变得更加简单
populateData() {
this.getData().subscribe(data => {
const books = this.formGroup.get('books') as FormArray;
books.clear();
data.books.forEach(b => {
books.push(this.createBookForm(b))
});
});
}
注意:我看不到声明具有唯一属性FormForm的formGroup的必要性,请参见stackoverflow question
中的其他回答