使用 FormArray 动态控制 FormGroups 的数量
Dynamically control the number of FormGroups with a FormArray
我正在尝试使用 FormArray 动态控制 FormGroup 的数量,以便设置 FormArray 长度。
myForm = this.fb.group({
formGroupsToAdd: ['5'],
formList: this.fb.array(this.getFormControls(5))
});
getFormControls(numberOfFormGroups: number) {
const myArray = new Array(numberOfFormGroups);
myArray.fill(this.fb.group({
length: [''],
width: [''],
height: ['']
}));
return myArray;
}
我也有办法用
得到这个formList: FormArray
get unitList() {
return this.myForm.get('formList') as FormArray;
}
但是,当我向 FormArray
中的单个控件添加值时,它会更新 FormArray
中的所有 FormGroup
。
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index">
<div [formGroup]="formList.controls[i]">
<pre>{{formList.controls[i].value | json}}</pre>
<pre>i = {{i}}</pre>
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
</div>
所以我的 formList.value
看起来像这样...
[
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
}
]
我需要一个 FormGroup
来包含它自己独特的 FormControl
值。
我做错了什么?为什么 [formGroup]="formList.controls[i]"
不能通过为每个 formGroup 提供唯一标识符来满足我的需求?
编辑:我已经为我的问题添加了一个 stackblitz。
https://stackblitz.com/edit/angular-ivy-sa7pbb?file=src/app/app.component.html
您应该使用 [formGroupName]="i"
而不是 [formGroup]="formList.controls[i]"
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index">
<div [formGroupName]="i">
<pre>{{formList.controls[i].value | json}}</pre>
<pre>i = {{i}}</pre>
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
</div>
你应该像这样使用 [formGroupName]="idx"。
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index" [formGroupName]="i">
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
以及一些有用的功能:
// Call init form on init
ngOnInit(): void {
this.initForm();
}
// init form here
initForm() {
this.myForm = this.fb.group({
formList: this.fb.array([])
});
// Call this 5 times or any times you want to init rows.
this.addItem();
}
// Add new item to make an addition button on UI
addItem() {
// You can enter input into newItem function to load data from API to make update/details screen.
this.unitList.push(this.newItem(0, 0, 0));
}
// Your function to get fromList
unitList() {
return this.myForm.get('formList') as FormArray;
}
// new Item as a FormGroup to add into main form and it will auto render on UI
newItem(length: number, width: number, height: number): FormGroup {
const newGroup = this.fb.group({
length: [length],
width: [width],
height: [height]
})
return newGroup;
}
// Clear all items to make a refresh/clean UI
clearAllList() {
this.unitList.clear();
}
// Remove item at index to make a delete button
removeItem(index: number) {
this.unitList.removeAt(idx);
}
已更新:
修复 stackblitz 上的问题:https://stackblitz.com/edit/angular-ivy-rtmpwc?file=src/app/app.component.ts
问题是 myArray.fill
,当您使用它时,它会使用 1 个参考变量来设置数组中的所有 5 个项目。因此,当您更改一项时,它将引用为 5 项
getFormControls(numberOfFormGroups) {
const myArray = new Array(numberOfFormGroups);
myArray.fill(this.fb.group({
length: [''],
width: [''],
height: ['']
}));
return myArray;
}
所以固定函数应该是这样的。它将为 5 个项目创建 5 个引用。
getFormControls(numberOfFormGroups) {
const myArray = new Array();
for (let i = 1; i <= numberOfFormGroups; i++) {
let newItem = this.fb.group({ length: [''], width: [''], height: [''] });
myArray.push(newItem);
}
return myArray;
}
我正在尝试使用 FormArray 动态控制 FormGroup 的数量,以便设置 FormArray 长度。
myForm = this.fb.group({
formGroupsToAdd: ['5'],
formList: this.fb.array(this.getFormControls(5))
});
getFormControls(numberOfFormGroups: number) {
const myArray = new Array(numberOfFormGroups);
myArray.fill(this.fb.group({
length: [''],
width: [''],
height: ['']
}));
return myArray;
}
我也有办法用
得到这个formList: FormArray
get unitList() {
return this.myForm.get('formList') as FormArray;
}
但是,当我向 FormArray
中的单个控件添加值时,它会更新 FormArray
中的所有 FormGroup
。
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index">
<div [formGroup]="formList.controls[i]">
<pre>{{formList.controls[i].value | json}}</pre>
<pre>i = {{i}}</pre>
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
</div>
所以我的 formList.value
看起来像这样...
[
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
},
{
"length": "",
"width": "asdf",
"height": ""
}
]
我需要一个 FormGroup
来包含它自己独特的 FormControl
值。
我做错了什么?为什么 [formGroup]="formList.controls[i]"
不能通过为每个 formGroup 提供唯一标识符来满足我的需求?
编辑:我已经为我的问题添加了一个 stackblitz。
https://stackblitz.com/edit/angular-ivy-sa7pbb?file=src/app/app.component.html
您应该使用 [formGroupName]="i"
而不是 [formGroup]="formList.controls[i]"
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index">
<div [formGroupName]="i">
<pre>{{formList.controls[i].value | json}}</pre>
<pre>i = {{i}}</pre>
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
</div>
你应该像这样使用 [formGroupName]="idx"。
<div formArrayName="formList">
<div *ngFor="let unitForm of formList.controls; let i = index" [formGroupName]="i">
<mat-form-field>
<input matInput formControlName="length" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="width" />
</mat-form-field>
<mat-form-field>
<input matInput formControlName="height" />
</mat-form-field>
</div>
</div>
以及一些有用的功能:
// Call init form on init
ngOnInit(): void {
this.initForm();
}
// init form here
initForm() {
this.myForm = this.fb.group({
formList: this.fb.array([])
});
// Call this 5 times or any times you want to init rows.
this.addItem();
}
// Add new item to make an addition button on UI
addItem() {
// You can enter input into newItem function to load data from API to make update/details screen.
this.unitList.push(this.newItem(0, 0, 0));
}
// Your function to get fromList
unitList() {
return this.myForm.get('formList') as FormArray;
}
// new Item as a FormGroup to add into main form and it will auto render on UI
newItem(length: number, width: number, height: number): FormGroup {
const newGroup = this.fb.group({
length: [length],
width: [width],
height: [height]
})
return newGroup;
}
// Clear all items to make a refresh/clean UI
clearAllList() {
this.unitList.clear();
}
// Remove item at index to make a delete button
removeItem(index: number) {
this.unitList.removeAt(idx);
}
已更新: 修复 stackblitz 上的问题:https://stackblitz.com/edit/angular-ivy-rtmpwc?file=src/app/app.component.ts
问题是 myArray.fill
,当您使用它时,它会使用 1 个参考变量来设置数组中的所有 5 个项目。因此,当您更改一项时,它将引用为 5 项
getFormControls(numberOfFormGroups) {
const myArray = new Array(numberOfFormGroups);
myArray.fill(this.fb.group({
length: [''],
width: [''],
height: ['']
}));
return myArray;
}
所以固定函数应该是这样的。它将为 5 个项目创建 5 个引用。
getFormControls(numberOfFormGroups) {
const myArray = new Array();
for (let i = 1; i <= numberOfFormGroups; i++) {
let newItem = this.fb.group({ length: [''], width: [''], height: [''] });
myArray.push(newItem);
}
return myArray;
}