Вложенные Реактивные формы FormArray

#angular #typescript #angular-reactive-forms #angular-forms

Вопрос:

Я пытаюсь создать вложенный массив форм внутри массива форм с угловыми реактивными формами, однако я получаю ошибку «Свойство» элементы управления «не существует в типе «AbstractControl»

Стекблитц выглядит так, как показано ниже

https://stackblitz.com/edit/angular-ivy-spyhf4?file=src/app/app.component.html

Я прокомментировал раздел, в котором я вижу ошибку, и она отмечена.

Где я ошибаюсь?

Ответ №1:

Пожалуйста, проверьте изменения, которые я внес в вложенный формат.

Рабочая демонстрация: stackblitz

 import { Component, VERSION } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms'; 
@Component({
   selector: 'my-app',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   name = 'Angular '   VERSION.major;
   webhooks = new FormArray([]);
   headers = new FormArray([]);

  createAlertProfileForm = new FormGroup({
     name: new FormControl(''),
     webhooks: this.webhooks
  });

  constructor() {}

  ngOnInit() {}

  addWebhook() {
     this.webhooks.push(
       new FormGroup({
         url: new FormControl(''),
         headers: new FormArray([])
       })
     );
  }

  removeWebhook(index: number) {
     this.webhooks.removeAt(index);
  }

  addHeader(webHookIndex) {
    let webHooks = this.webhooks.controls[webHookIndex];
    console.log(webHooks);
    if (webHooks) {
       (<FormArray>webHooks.get('headers')).push(
         new FormGroup({
           key: new FormControl(''),
           value: new FormControl('')
         })
       );
     } else {
        console.log(webHookIndex, this.webhooks.controls);
   (<FormGroup>this.webhooks.controls[webHookIndex]).addControl(
    'headers',
    new FormArray([
      new FormGroup({
        key: new FormControl(''),
        value: new FormControl('')
      })
    ])
  );
}
 }

 removeHeader(index: number) {
   this.headers.removeAt(index);
 }

 createAlertProfile() {
   console.log(this.createAlertProfileForm.value);
 }
}
 

 <form [formGroup]="createAlertProfileForm" (ngSubmit)="createAlertProfile()">
    <div class="dialog-body">

        <div>
            <label for="name">Name</label>
            <input id="name" placeholder="Name" formControlName="name" />
        </div>

        <div>
            <div>
                <h3>Webhook</h3>

                <button type="button" class="btn btn--accent-transparent btn--small" (click)="addWebhook()">
                    Add Webhook
                </button>
            </div>

            <div *ngIf="!webhooks.length">
                <p class="form-array-section-no-data">No webhooks yet</p>
            </div>

            <ng-container formArrayName="webhooks">
                <div *ngFor="let control of webhooks.controls;let i = index;"
                    style="display: flex; flex-direction: column;">
                    <div>
                        <div [formGroupName]="i">
                            <input matInput placeholder="Url" formControlName="url" />

                            <div formArrayName="headers">
                                <div *ngFor="let con of control.get('headers')['controls']; let j = index">
                                    <div>
                                        <div [formGroupName]="j">
                                            <input matInput placeholder="Url" formControlName="key" />
                                            <input matInput placeholder="Url" formControlName="value" />
                                        </div>
                                        <div class="form-array-section-header">
                                            <h3>Header</h3>

                                        </div>

                                    </div>
                                </div>
                                <button type="button" class="btn btn--accent-transparent btn--small"
                                    (click)="addHeader(i)">
                                    Add Header
                                </button>
                            </div>

                        </div>
                        <button type="button" class="btn btn--transparent btn--small"
                            (click)="removeWebhook(i)">Remove
                        </button>
                    </div>
                </div>
            </ng-container>
        </div>

        <div style="padding-top:20px">
            <button type="submit" [disabled]="!createAlertProfileForm.valid">
                <i class="fas fa-plus-circle"></i> Add Profile
            </button>
        </div>
    </div>
</form>
 

введите описание изображения здесь

Комментарии:

1. Если вы выполните следующие действия, у вас не может быть более 1 веб-крючка, потому что все заголовки будут связаны с первым

2. @Alexis прав в том, что я добавляю заголовки ко всем веб-книгам. Любые лучшие решения.

3. Пожалуйста, проверьте еще раз этот ответ и поделитесь своими отзывами.

4. @Спасибо, чинтан, я проверю это еще раз в ближайшее время. Я пытался удалить заголовок, и оказалось сложно, как я могу удалить заголовок с отдельного веб-крючка.

5. Неважно, что мне это удалось с помощью removeHeader(webHookIndex: номер, headerIndex: номер) { пусть webHooks = это. webhooks.controls[webHookIndex]; if (webHooks) { (<FormArray>webHooks.get(‘заголовки’)).RemoveAt(headerIndex); } } спасибо всем за помощь.

Ответ №2:

Ошибка исходит из строки 42, замените строку ниже; это устранит проблему.

 *ngFor="let con of control.get('headers')['controls']
 

Ответ №3:

Вы можете создать метод для возврата элементов управления следующим FormArray образом

 getHeaderControl(control){
  return control.get('headers') as FormArray
}
 

Затем используйте его в своем шаблоне следующим образом

 <div *ngFor="let con of getHeaderControl(control).controls;index as j">