迁移到 Angular 15 后找不到路径错误的控件

问题描述 投票:0回答:1

从 Angular 10 迁移到 Angular 15 导致控制台出现以下错误:

ERROR 错误:找不到路径为“mappedHeaders -> 0 -> 的控件” 价值'

示例.ts

this.headerArray = this.fb.array([]);
this.formGroup = this.fb.group({
  mappedHeaders: this.headerArray
});

初始化后在控制台上打印 this.headerArray 的结构:

form array first element

推送值后在控制台上打印 this.formGroup 的结构: formGroup.controls

example.html:

   <div [formGroup]="formGroup">
    <table>
      <tbody formArrayName="mappedHeaders">
      <ng-container *ngFor="let header of accountHeaders; index as i">
        <tr>
          <td>{{i}}</td>
          <td [formGroupName]="i">
            <select class="ui fluid clearable selection search dropdown column-mapping-dropdown" formControlName="value">
              <option *ngFor="let header of fileHeaders" [value]="header">{{ header }}</option>
            </select>
          </td>
        </tr>
      </ng-container>
      </tbody>
    </table>
  </div>

accountHeaders
是一个字符串数组,例如
['one', 'two', 'three',...'etc']

上述代码在 Angular 10 中完美运行。我检查过其他类似的问题,但没有一个可以解决这个问题。

angular angular-forms formarray angular15 angular2-formbuilder
1个回答
0
投票

当表单数组内没有 formGroup,但我们正在使用具有值的数据对象运行 for 循环,但表单数组没有相应的表单组时,会发生此错误。

我们可以对数据对象运行 for 循环并创建表单组,我们还应该循环遍历控件而不是数据对象,这将完全消除此错误!

import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import {
  ReactiveFormsModule,
  FormBuilder,
  FormArray,
  FormGroup,
  FormControl,
} from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule, CommonModule],
  template: `
    <div [formGroup]="formGroup">
    <table>
      <tbody formArrayName="mappedHeaders">
      <!-- changed below -->
      <ng-container *ngFor="let header of formArrayControls; index as i">
        <tr>
          <td>{{i}}</td>
          <td [formGroupName]="i">
            <select class="ui fluid clearable selection search dropdown column-mapping-dropdown" formControlName="value">
              <option *ngFor="let header of fileHeaders" [value]="header">{{ header }}</option>
            </select>
          </td>
        </tr>
      </ng-container>
      </tbody>
    </table>
  </div>
  {{formGroup.value | json}}
  `,
})
export class App {
  fb = inject(FormBuilder);
  headerArray = this.fb.array([]);
  formGroup = this.fb.group({
    mappedHeaders: this.headerArray,
  });
  accountHeaders = ['one', 'two', 'three'];
  fileHeaders = [1, 2, 3];

  get formArrayControls() {
    const formArray = this.formGroup.get('mappedHeaders') as FormArray;
    return formArray.controls;
  }

  ngOnInit() {
    if (this.accountHeaders?.length) {
      const formArray = this.formGroup.get('mappedHeaders') as FormArray;
      this.accountHeaders.forEach((item: string) => {
        const group = new FormGroup({ value: new FormControl(item) });
        formArray.push(group);
      });
    }
  }
}

bootstrapApplication(App);

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.