Change FormBuilder array items in nested forms

2019-02-20 10:46发布

问题:

According to the API documentation the proper way to change nested values is to use method patchValue

myForm.patchValue({'key': {'subKey': 'newValue'}});

But how to change values in nested arrays like list of cars in this example below. How to get first item of list array an change model to Fiesta? Plunker

myForm.patchValue({'list': 0: {'model': 'Fiesta'}); is not working.

@Component({
  moduleId: __moduleName,
  selector: 'my-app',
  template: `<div><pre>{{ myForm.value | json }}</pre></div>`
})
export class AppComponent {

  public myForm: FormGroup;

  constructor(@Inject(FormBuilder) private _fb: FormBuilder) {

    this.myForm = this._fb.group({
      name: 'Cars',
      list:  this._fb.array([
        this.initCar(),
        this.initCar(),
        this.initCar()
      ]),
    });
    /** Change value Here **/
    this.myForm.patchValue({name: 'Automobile'});
  };

  initCar() {
    return this._fb.group({
      automaker: 'Ford',
      model:     'Fusion'
    });
  }
}

Plunker

回答1:

I did something similar not that long ago just add.

const patchV = (<FormArray>this.myForm.controls['list']).at(0) as FormArray;
patchV.patchValue({automaker: 'CoolCar', model: 'Bucket'})

Working Example [plunker]http://embed.plnkr.co/VWicnA/



回答2:

Here is a way to access and patch a FormArray in Angular 2. I have modified your code to get this to work using your Plunk.

import { Inject, Component } from '@angular/core';
import { FormBuilder, FormArray }       from '@angular/forms';

@Component({
  moduleId: __moduleName,
  selector: 'my-app',
  template: `<div><pre>{{ myForm.value | json }}</pre></div>`
})
export class AppComponent {

  public myForm: FormGroup;

  constructor(@Inject(FormBuilder) private _fb: FormBuilder) {

    this.myForm = this._fb.group({
      name: 'Cars',
      list:  this._fb.array([
        this.initCar(),
        this.initCar(),
        this.initCar()
      ]),
    });

    this.myForm.patchValue({name: 'Automobile'});

    /** Make changes here ***/
    // access the array from the form
    var items = this.myForm.get('list');

    // change the first item
    items.patchValue([{
      model: 'Fiesta'
    }]);

    // change the second item (notice the comma in front of the array)
    items.patchValue([,
    {
      model: 'TLX',
      automaker: 'Acura'
    }]);

    // change the third item (notice the 2 commas in front of the array)
    items.patchValue([,,
    {
      model: 'Accord',
      automaker: 'Honda'
    }]);

  };

  initCar() {
    return this._fb.group({
      automaker: 'Ford',
      model:     'Fusion'
    });
  }

}

Output before:

{
  "name": "Automobile",
  "list": [
    {
      "automaker": "Ford",
      "model": "Fusion"
    },
    {
      "automaker": "Ford",
      "model": "Fusion"
    },
    {
      "automaker": "Ford",
      "model": "Fusion"
    }
  ]
}

Output after:

{
  "name": "Automobile",
  "list": [
    {
      "automaker": "Ford",
      "model": "Fiesta"
    },
    {
      "automaker": "Acura",
      "model": "TLX"
    },
    {
      "automaker": "Honda",
      "model": "Accord"
    }
  ]
}

EDIT: A better solution:

// access the array from the form
var items = this.myForm.get('list');

const item1 = (items).at(0);
// change the first item
item1.patchValue({model: 'Fiesta'});

// change the second item
const item2 = (items).at(1);
item2.patchValue({
  model: 'TLX',
  automaker: 'Acura'
});

// change the third item
const item3 = (items).at(2);
item3.patchValue({
  model: 'Accord',
  automaker: 'Honda'
});