[Angular] Working with FormArray

'FormArray' can work with array of 'FormGroup' or 'FormControl'.

  form = new FormGroup({
    stock: new FormArray([
      new FormGroup({
        product_id: new FormControl(1),
        quantity: new FormControl(10)
      }),
      new FormGroup({
        product_id: new FormControl(12),
        quantity: new FormControl(90)
      }),
    ])
  });

So for Javascript, we have a 'form=new FormGroup()', inside formGoup, we have a 'stock' formArray with multi formGroup inside.

In the html, we use component approach:

        <stock-products
          (removed)="removeStock($event)"
          [parent]="form">
        </stock-products>

We create a custom component.

Inside the component:

import { Component, Input } from '@angular/core';
import { FormGroup, FormArray } from '@angular/forms';

@Component({
  selector: 'stock-products',
  styleUrls: ['stock-products.component.scss'],
  template: `
    <div class="stock-product" [formGroup]="parent">
      <div formArrayName="stock">
        <div
          *ngFor="let item of stocks; let i = index;">
          
          <div class="stock-product__content" [formGroupName]="i">
            <div class="stock-product__name">
              {{ item.value.product_id }}
            </div>
            <input 
              type="number"
              step="10"
              min="10"
              max="1000"
              formControlName="quantity">
            <button type="button">
              Remove
            </button>
          </div>

        </div>
      </div>
    </div>
  `
})
export class StockProductsComponent {
  @Input()
  parent: FormGroup;

  get stocks() {
    return (this.parent.get('stock') as FormArray).controls;
  }

}

First:

<div class="stock-product" [formGroup]="parent">

Tells what want to bind 'form' object passing down from the parent component.

Then to keep the same structure, we add:

<div formArrayName="stock">

Because "stock" is a FormArray.

Inside the Form array, we loop thought each form group:

<div class="stock-product__content" [formGroupName]="i">

We use the index as key to bind 'formGroupName', it actually feeling the same as work with JS array, accessing by the index.

Notice how we get 'stock' from 'form':

  get stocks() {
    return (this.parent.get('stock') as FormArray).controls;
  }

Using 

(this.parent.get('stock') as FormArray)

just to tell Typescrpt, this is a FormArray type.

The same as :

    get stocks() {
        const ary = <FormArray>this.parent.get('stock');
        return ary.controls;
    }

To add or remove from the FormArray: we have 'push' and 'removeAt' methods

  addStock(stock) {
    const control = this.form.get('stock') as FormArray;
    control.push(this.createStock(stock));
  }

  removeStock({ group, index }: { group: FormGroup, index: number }) {
    const control = this.form.get('stock') as FormArray;
    control.removeAt(index);
  }



原文地址:https://www.cnblogs.com/Answer1215/p/6592580.html