Angular 在 formArray 中嵌套 formGroups 的响应式表单

Angular Reactive Forms with nested formGroups inside a formArray

我正在构建一个具有以下结构的表单:

{
  "name": "root_test_name",
  "definition": {
    "name": "definition_test_name",
    "components": [
      {
        "name": "component_0_name",
        "info": {
          "name": "info_component_0_name"
        }
      },
      {
        "name": "component_1_name",
        "info": {
          "name": "info_component_1_name"
        }
      },
      {
        "name": "component_2_name",
        "info": { <--Error on all attempts to set the formGroup name for this one :(
          "name": "info_component_2_name" 
        }
      }
    ]
  }
}

使用响应式表单,我能够显示所有项目的控件,“信息”表单组中的“名称”除外。 Stackblitz 演示 here

这是我的 AppComponent:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Angular ' + VERSION.major;

  constructor(private fb: FormBuilder) {
    this.addComponent('component_0_name');
    this.addComponent('component_1_name');
    this.addComponent('component_2_name');
  }

  componentForm = this.fb.group({
    name: ['root_test_name', Validators.required],
    definition: this.fb.group({
      name: ['definition_test_name'],
      components: this.fb.array([]),
    }),
  });

  components(): FormArray {
    return this.componentForm.get('definition').get('components') as FormArray;
  }

  componentInfo(componentIndex: number): FormGroup {
    return this.components().at(componentIndex) as FormGroup;
  }

  addComponent(name: string) {
    let component = this.fb.group({
      name: [name],
      info: this.fb.group({
        name: ['info_' + name],
      }),
    });

    this.components().push(component);
  }
}

这是模板:

<hello name="{{ name }}"></hello>
<p>Start editing to see some magic happen :)</p>

<div [formGroup]="componentForm">
  <input type="text" formControlName="name" />

  <div style="padding-left:10px" formGroupName="definition">
    <input type="text" formControlName="name" />

    <div>Components</div>
    <div formArrayName="components">
      <div *ngFor=" let component of components().controls; let componentIndex = index " >
        <div style="padding-left:10px [formGroupName]="componentIndex">
          <input type="text" formControlName="name" />

          <!-- 1st attempt to get to get name out of info formGroup 
          ERROR: Property 'info' does not exist on type 'AppComponent'-->
          <!-- <div [formGroupName]="info">
            <input type="text" formControlName="name" />
          </div> -->

          <!-- 2nd attempt
          ERROR: Type 'FormGroup' is not assignable to type 'string | number'-->
          <!-- <div style="padding-left:15px" [formGroupName]="componentInfo(componentIndex)" >
            <input type="text" formControlName="name" />
          </div> -->
        </div>
      </div>
    </div>
  </div>
</div>

<pre>{{ componentForm.value | json }}</pre>

如何设置“信息”组件的 formGroup 名称,以便“名称”控件显示值。

使用 formGroupName 而不是 [formGroupName]

<div formGroupName="info">
    <input type="text" formControlName="name" />
</div>

Sample Demo on StackBlitz


参考

Angular - Register a nested FormGroup.