如何用 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.