Вложенные формы динамических массивов в формах Angular Reactive

У меня есть форма массива, а именно «адрес», и она будет динамической, как только пользователь нажмет кнопку «Добавить адрес», сразу же добавится одна форма адреса. Я реализовал это с проблемой (Добавить / удалить адрес работает нормально). Теперь мне нужно добавить динамические контактные номера, похожие на адрес.

Адрес может содержать один или несколько телефонных номеров. Если пользователь нажимает «Добавить номер телефона», необходимо добавить новую форму телефонного номера внутри адресной формы, функциональные возможности потребуются во всех адресных формах. (т.е. массив массива => массив адресов, и каждый адрес содержит массив контактов)

Рабочий код доступен в 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');
  }

}

Пожалуйста, помогите мне, как реализовать формы динамического вложенного массива (добавить / удалить формы).


person B.Balamanigandan    schedule 22.03.2019    source источник
comment
Вы можете просто получить контакты как FormArray и нажать группу контактов. Аналогично тому, как вы это делали для адреса.   -  person Sachin Gupta    schedule 22.03.2019
comment
@SachinGupta У меня в этом замешательство. не могли бы вы объяснить исходный код в разделе ответов.   -  person B.Balamanigandan    schedule 22.03.2019
comment
@SachinGupta - URL-адрес stackblitz: stackblitz.com/edit/angular-6gwmmu   -  person B.Balamanigandan    schedule 22.03.2019
comment
В вашем примере есть ошибки. Все элементы formControls не указаны   -  person Sachin Gupta    schedule 22.03.2019
comment
@ B.Balamanigandan, вы можете использовать его как ссылку stackblitz.com/edit / angular-reactive-forms-deep-nested-a9cjz9, и это поможет вам создать вложенную реактивную форму ..   -  person Maniraj Murugan    schedule 22.03.2019


Ответы (2)


Вам необходимо правильно объявить в соответствии с formGroup или formArrays.

Вы можете использовать this как ссылку.

Редактировать

Разветвленный код: здесь. Как упоминалось выше, держите 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>

person Sachin Gupta    schedule 22.03.2019

Попробуйте следующий способ. Передайте индекс для адреса в представлении, прочтите элемент контактов для этого конкретного адреса и добавьте новую contactGroup.

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

Надеюсь это поможет!!!

person Harshana    schedule 22.03.2019
comment
Я пробовал не работать. Рабочий код доступен в StackBlitz: stackblitz.com/edit/angular-maexn8. Не могли бы вы дать свое решение в StackBlitz - person B.Balamanigandan; 22.03.2019