如何用 2 个数组做 FormArray
How to do FormArray with 2 arrays
我想做这样的东西。使用 angular FormArray。在 Name 的数组上,Quantity 的一个数组。我来做一个而不是 2 :(
如果有人有想法。 :)
我想做成这样:
PS: 我没有写我做的所有测试代码。我刚刚编写了适用于一个数组的代码。我写的也是没有提交按钮来简化代码。
项目来自 JSON 文件,我还写了它的结构
非常感谢您的帮助
page.ts
itemForm: FormGroup;
initForm(array: InfoModel[]) {
this.infoForm = this.formBuilder.group({
name: this.formBuilder.array([]),
quantity: this.formBuilder.array([])
});
}
onAddMoreItem() {
const nameControl = this.formBuilder.control(null, Validators.required);
this.getItemName().push(nameControl);
}
getItemName(): FormArray {
return this.itemForm.get('name') as FormArray;
}
模板
<form [formGroup]="itemForm" (ngSubmit)="onSave()">
<div formArrayName="name">
<h3>Items</h3>
<div *ngFor="let adControl of getName().controls; let i = index">
<input type="text" [formControlName]="i">
</div>
<button type="button" (click)="onAddMoreItem()">Add more item</button>
</div>
</form>
JSON 文件
"item": [
{
"name" : [ "aaa", "bbb" ],
"quantity" : [ "130", "60" ]
}
]
Angular 响应式表单旨在与集合数据模型一起使用。如果您希望表单的外观和行为与您所显示的一样,则必须更改数据模型。
您想要的是 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']);
}
}
模板看起来像这样:
<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 }}</pre>
<h2>Data</h2>
<p>This will only reflect after Submit</p>
<pre>{{ data | json }}</pre>
Here's a Working Sample StackBlitz for your ref.
我想做这样的东西。使用 angular FormArray。在 Name 的数组上,Quantity 的一个数组。我来做一个而不是 2 :(
如果有人有想法。 :)
我想做成这样:
PS: 我没有写我做的所有测试代码。我刚刚编写了适用于一个数组的代码。我写的也是没有提交按钮来简化代码。
项目来自 JSON 文件,我还写了它的结构
非常感谢您的帮助
page.ts
itemForm: FormGroup;
initForm(array: InfoModel[]) {
this.infoForm = this.formBuilder.group({
name: this.formBuilder.array([]),
quantity: this.formBuilder.array([])
});
}
onAddMoreItem() {
const nameControl = this.formBuilder.control(null, Validators.required);
this.getItemName().push(nameControl);
}
getItemName(): FormArray {
return this.itemForm.get('name') as FormArray;
}
模板
<form [formGroup]="itemForm" (ngSubmit)="onSave()">
<div formArrayName="name">
<h3>Items</h3>
<div *ngFor="let adControl of getName().controls; let i = index">
<input type="text" [formControlName]="i">
</div>
<button type="button" (click)="onAddMoreItem()">Add more item</button>
</div>
</form>
JSON 文件
"item": [
{
"name" : [ "aaa", "bbb" ],
"quantity" : [ "130", "60" ]
}
]
Angular 响应式表单旨在与集合数据模型一起使用。如果您希望表单的外观和行为与您所显示的一样,则必须更改数据模型。
您想要的是 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']);
}
}
模板看起来像这样:
<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 }}</pre>
<h2>Data</h2>
<p>This will only reflect after Submit</p>
<pre>{{ data | json }}</pre>
Here's a Working Sample StackBlitz for your ref.