Angular 表格数组

Angular FormArray

我无法访问 Angular 13.3 中的 FormArray。它在控制台中显示此错误。我有一个表单组,里面还有 2 个表单组和 1 个表单数组。

core.mjs:6485 ERROR Error: Cannot find control with name: 'third'

这是我的 HTML 代码:

<form [formGroup]="form" (ngSubmit)="onSubmit()">

  <div [formGroup]="bankFormGroup">

    <input type="text" placeholder="property11" formControlName="property11">

    <div *ngIf="bankFormGroup.get('property11')?.invalid && (bankFormGroup.get('property11')?.dirty || bankFormGroup.get('property11')?.touched)" class="alert">

      <div *ngIf="bankFormGroup.get('property11')?.errors?.['required']">
        Required.
      </div>
    </div>

    <div [formGroup]="bankForm2Group">

      <input type="text" placeholder="property21" formControlName="property21">

      <div *ngIf="bankForm2Group.get('property21')?.invalid && (bankForm2Group.get('property21')?.dirty || bankForm2Group.get('property21')?.touched)" class="alert">

        <div *ngIf="bankForm2Group.get('property21')?.errors?.['required']">
          Required.
        </div>
      </div>
    </div>

    <ul class="list-group">

      <li class="list-group-item" formArrayName="third" *ngFor="let product of bankForm3Group.controls; let i = index;">

        <div [formGroupName]="i" class="row">

          <div class="col-4">

            <input type="text" formControlName="property3" class="form-control" id="property3" placeholder="property3">
          </div>
        </div>
      </li>
    </ul>
  </div>

  <div [formGroup]="bankFormGroup">

    <input type="text" placeholder="property12" formControlName="property12">
  </div>

  <button type="submit">Submit</button>
</form>

TS代码:

declare var $: any;
import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-first',
  templateUrl: './first.component.html',
  styleUrls: ['./first.component.css']
})
export class FirstComponent implements OnInit {
  form!: FormGroup;

  constructor() {
    this.form = new FormGroup({
      first: new FormGroup({
        property11: new FormControl('property 1.1', Validators.required),
        property12: new FormControl('property 1.2', Validators.required)
      }),

      second: new FormGroup({
        property21: new FormControl('property 2.1', Validators.required)
      }),

      third: new FormArray([
        new FormGroup({
          property3: new FormControl('property 3')
        }),
        new FormGroup({
          property3: new FormControl('property 3')
        }),

      ])
    });
  }

  get bankFormGroup(): FormGroup {
    return this.form?.get('first') as FormGroup;
  }

  get bankForm2Group(): FormGroup {
    return this.form?.get('second') as FormGroup;
  }

  get bankForm3Group(): FormArray {
    return this.form?.get('third') as FormArray;
  }

  //get third(): FormArray {
  //  return this.form?.get('third') as FormArray;

  //}

  onSubmit() {
    console.log('Submit', this.form.value);
  }

  ngOnInit(): void {
    $(".preloader").hide();
  }
}

我在 TS 中有单独的 FormGroup,但在 HTML 中它是嵌套的。我创建 Getter 几乎解决了的方法。但我无法通过此访问 FormArray。我花了很多时间但没有运气。提前致谢。

主要问题是你的“divs”关闭错误。在这个 stackblitz 我订购了你的 div .html.

注意 1:您可以使用 formGroupName="first"formGroupName="second" 代替 [formGroup]="bankFormGroup"[formGroup]="backForm2Group"

注意2:你可以在你的*ngIf中使用form.get('formgroupname.formControlName')的方式,例如

<div *ngIf="form.get('second.property21')?.invalid>...</div>

注意 3:我更喜欢 formArrayName="third" 在 <ul> 而不是 <li> 和 *ngFor(但这是个人意见)

注意 4:对我来说很奇怪。html 你显示输入“属性 1.1”(来自 formGroup“first”)和“属性 1.2”(来自 formGroup“second”),最后输入输入“属性 1.2”(来自 formGroup“first”)

谢谢@Eliseo,我的要求已经达到了。我使用 <ng-container> 来分隔表单组及其元素。通过这种方法,我也不再需要 getter 方法。这是我更新的代码

HTML:

<form [formGroup]="form" (ngSubmit)="onSubmit()">

  <!--classess removed for clarity-->
  <!--parent div contains first and second group. ng container has been used for each group-->
  <div>

    <!--accessing first group-->
    <ng-container formGroupName="first">
      <input type="text" placeholder="property11" formControlName="property11">

      <div *ngIf="form.get('first.property11')?.invalid && (form.get('first.property11')?.dirty || form.get('first.property11')?.touched)" class="alert">

        <div *ngIf="form.get('first.property11')?.errors?.['required']">
          Required.
        </div>
      </div>
    </ng-container>

    <!--classess removed for clarity-->
    <div>

      <!--accessing second group-->
      <ng-container formGroupName="second">
        <input type="text" placeholder="property21" formControlName="property21">

        <div *ngIf="form.get('second.property21')?.invalid && (form.get('second.property21')?.dirty || form.get('second.property21')?.touched)" class="alert">

          <div *ngIf="form.get('second.property21')?.errors?.['required']">
            Required.
          </div>
        </div>
      </ng-container>
    </div>

    <ul>
      <!--accessing third array-->
      <ng-container formArrayName="third">
        <li *ngFor="let product of third.controls; let i = index;">

          <div [formGroupName]="i">

            <div>

              <input type="text" formControlName="property3" id="property3" placeholder="property3">
            </div>
          </div>
        </li>
      </ng-container>
    </ul>
  </div>

  <!--classess removed for clarity-->
  <div>
    <!--accessing first group back again-->
    <ng-container formGroupName="first">
      <input type="text" placeholder="property12" formControlName="property12">
    </ng-container>
  </div>

  <button type="submit">Submit</button>
</form>

TS代码:

declare var $: any;
import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-first',
  templateUrl: './first.component.html',
  styleUrls: ['./first.component.css']
})
export class FirstComponent implements OnInit {
  form!: FormGroup;

  constructor() {
    this.form = new FormGroup({
      first: new FormGroup({
        property11: new FormControl('property 1.1', Validators.required),
        property12: new FormControl('property 1.2', Validators.required)
      }),

      second: new FormGroup({
        property21: new FormControl('property 2.1', Validators.required)
      }),

      third: new FormArray([
        new FormGroup({
          property3: new FormControl('property 3')
        }),
        new FormGroup({
          property3: new FormControl('property 3')
        }),

      ])
    });
  }

  get third(): FormArray {
    return this.form?.get('third') as FormArray;
  }

  onSubmit() {
    console.log('Submit', this.form.value);
  }

  ngOnInit(): void {
    $(".preloader").hide();
  }
}

如果有任何改进的余地,请告诉我。我会更新代码。