Как сделать FormArray с 2 массивами - PullRequest
0 голосов
/ 22 июня 2019

Я бы хотел сделать что-то подобное.С угловым FormArray.В массив для имени, один массив для количества.Я прибываю, чтобы сделать это для одного, но не для 2: (

Если у кого-то есть идея.:)

Я хотел бы сделать это так: enter image description here

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" ]
    }
]

1 Ответ

0 голосов
/ 22 июня 2019

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 для вашей ссылки.

...