Angular 反应形式中的嵌套动态数组形式

Nested dynamic array forms in Angular Reactive forms

我有一个数组形式,即 "address",一旦用户单击 "Add Address" 按钮,这将是动态的,将立即添加一个地址形式。我实现这个有一个问题(Add/Remove 地址工作正常)。现在我需要添加一个类似于地址的动态联系电话。

一个地址可能包含一个或多个phone号码,如果用户点击"Add Phone number"需要在地址表单中添加一个新的phone号码表单,该功能将所有地址表都需要。 (即,数组数组=>地址数组,每个地址包含联系人数组)

StackBlitz 中提供了工作代码:https://stackblitz.com/edit/angular-maexn8

示例代码:

import { Injectable } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
import { User } from '../../model/user';

@Injectable()
export class UpsertUserFormService {

  public userForm: FormGroup;

  constructor(private _fb: FormBuilder) {
    this.userForm = this._fb.group({
      relation: [],
      title: [],
      firstName: [],
      lastName: [],
      address: this._fb.array([this.addAddressGroup()])
    });
  }

  private addAddressGroup(): FormGroup {
    return this._fb.group({
      street: [],
      city: [],
      state: [],
      pincode: [],
      isPrimary: [],
      contacts: this._fb.array([this.contactsGroup()]) 
    });
  }

  showMessage(obj: any) {
    console.log('Console Item: ',obj)
  }

  private contactsGroup(): FormGroup {
    return this._fb.group({
      phoneNumber: ['9712345678', [Validators.maxLength(10)]], 
    });
  }

  addAddress(): void {
    this.addressArray.push(this.addAddressGroup());
    console.log(this.addressArray);
  }

  removeAddress(index: number): void {
    this.addressArray.removeAt(index);
  }

  get addressArray(): FormArray {
    return <FormArray>this.userForm.get('address');
  }

}

请帮助我如何实现动态嵌套数组形式(Add/Remove 形式)。

试试下面的方法。传递视图中地址的索引并读取该特定地址的联系人元素并添加新的联系人组。

addPhoneNumber(index: number): void {
    this.addressArray[index].contacts.push(this.contactsGroup());
    console.log(this.addressArray[index].contacts);
}

希望对您有所帮助!!!

您需要按照formGroupformArrays正确申报。

可以参考this

编辑

分叉您的代码:here。如上所述,保持group/array/controls顺序

App.component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  public userForm: FormGroup;
  constructor(private _fb: FormBuilder) {
    this.userForm = this._fb.group({
      firstName: [],
      lastName: [],
      address: this._fb.array([this.addAddressGroup()])
    });
  }

  private addAddressGroup(): FormGroup {
    return this._fb.group({
      street: [],
      city: [],
      state: [],
      contacts: this._fb.array([])
    });
  }

  addAddress(): void {

    this.addressArray.push(this.addAddressGroup());

    console.log(this.addressArray);
  }

  removeAddress(index: number): void {
    this.addressArray.removeAt(index);
  }

  get addressArray(): FormArray {
    return <FormArray>this.userForm.get('address');
  }

  addContact(index): void {
    
    (<FormArray>(<FormGroup>this.addressArray.controls[index]).controls.contacts).push(this.contactsGroup());
  }

  private contactsGroup(): FormGroup {
    return this._fb.group({
      contactPerson: [],
      phoneNumber: ['9712345678', [Validators.maxLength(10)]], 
    });
  }

  addPhoneNumber(index: number): void {
    this.addressArray[index].contacts.push(this.contactsGroup());
    console.log(this.addressArray[index].contacts);
  }
}

## App.component.html ##
<h3>Users Creation</h3>

<form class="example-form" [formGroup]="userForm">
 <div class="primary-container">
    <input matInput placeholder="First Name" value="" formControlName="firstName">
    <input matInput placeholder="Last Name" value="" formControlName="lastName">
 </div>
 <div class="address-container" *ngFor="let group of addressArray.controls; let i = index;" formArrayName="address">
  <div [formGroupName]='i'>
   <input matInput placeholder="Street" value="" formControlName="street"> 
      <input matInput placeholder="City" value="" formControlName="city">
      <input matInput placeholder="State" value="" formControlName="state">
    
    <div formArrayName='contacts'>
      <div *ngFor="let subgroup of group.controls.contacts.controls; let idx = index;" [formGroupName]="idx">
        <input matInput placeholder="Contact Person" value="" formControlName="contactPerson">
        <input matInput placeholder="Phone Number" value="" formControlName="phoneNumber">
      </div>
      <button mat-raised-button (click)="addContact(i)">Add more Contacts</button>
    </div>
    </div>
  </div>
  <div class="form-row org-desc-parent-margin">
    <button mat-raised-button (click)="addAddress()">Add more address</button>
  </div>
</form>