Angular Reactive Forms предназначены для работы с заданной моделью данных. Если вы хотите, чтобы форма выглядела и вела себя так, как вы это показали, вам придется изменить модель данных.
То, что вы хотите, это FormArray
, который будет иметь FormGroup
с. Каждый FormGroup
будет иметь name
FormControl
и quantity
FormControl
.
Итак, что можно сделать, вы можете преобразовать фактические данные, чтобы они были готовы. И если вы хотите данные в предыдущем формате, вы можете снова преобразовать данные формы в структуру, которую вы хотите. Для этого вам нужно создать два метода преобразования.
Вот как бы вы поступили так:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms';
interface Item {
name: Array<string>;
quantity: Array<string>;
};
interface Data {
item: Array<Item>;
};
interface FormItem {
name: string;
quantity: string;
};
interface FormData {
data: Array<FormItem>;
};
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
data = {
item: [
{
name: ["aaa", "bbb"],
quantity: ["130", "60"]
}
]
};
formData;
form: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
const formData = this.transformDataToFormData(this.data);
this.form = this.fb.group({
data: this.fb.array(formData.data.map((datum: FormItem) => this.fb.group({
name: [datum.name],
quantity: [datum.quantity]
})))
});
}
onFormSubmit() {
console.log(this.form.value);
this.data = this.transformFormDataToData(this.form.value);
}
addItem() {
this.formDataArray.push(this.fb.group({
name: [],
quantity: []
}));
}
removeItem(itemIndex: number) {
this.formDataArray.removeAt(itemIndex);
}
private transformDataToFormData(data: Data): FormData {
return {
data: data.item[0].name
.map(
(name: string, index: number) => ({ name, quantity: data.item[0].quantity[index] }))
};
}
private transformFormDataToData(formData: FormData): Data {
return {
item: [{
name: formData.data.map((datum: FormItem) => datum.name),
quantity: formData.data.map((datum: FormItem) => datum.quantity),
}]
};
}
private get formDataArray(): FormArray {
return (<FormArray>this.form.controls['data']);
}
}
И шаблон будет выглядеть примерно так:
<code><form
[formGroup]="form"
(submit)="onFormSubmit()">
<div
formArrayName="data"
*ngFor="let item of form.controls['data'].controls; let i = index;"
>
<div [formGroupName]="i">
<input type="text" formControlName="name">
<input type="text" formControlName="quantity">
<button type="button" (click)="removeItem(i)">Remove</button>
</div>
<br>
</div>
<button type="button" (click)="addItem()">Add new Item</button>
<button type="submit">Submit</button>
</form>
<hr>
<h2>Form Data</h2>
<pre>{{ form.value | json }}
Данные
Это будет отражено только после отправки
{{ data | json }}
Вот Рабочий образец StackBlitz для вашей ссылки.