嵌套 FormArray 响应式表单

Nested FormArray Reactive Forms

我正在尝试使用 Angular 反应式表单在 FormArray 中实现嵌套的 formArray,但是我收到错误消息 '属性 'controls' 在类型 'AbstractControl'[ 上不存在=11=]

Stackblitz 如下

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

我已经注释掉了我看到错误的部分并做了标记。

我哪里错了?

您可以创建一个方法来 return 作为 FormArray 的控件,如下所示

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

然后在您的模板上使用它,如下所示

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

错误来自第 42 行, 替换下面的行;它会解决问题。

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

请检查我对嵌套 formArray 所做的更改。

工作演示: 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>