Angular Reactive Form - 如何定位嵌套在数组和对象中的表单控件

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

我是 Angular 的新手,我正在尝试为我一直在构建的食品配送系统构建一个相当复杂的表单。

我目前正在构建一个表单,使我能够将菜单项添加到餐厅的菜单中。

我已经构建了一个 Angular 表单来执行此操作,该表单的一部分包括一个插件部分,它与酱汁、口味等相关。数据的结构方式是有一个

addons
数组包含包含插件类型的插件对象以及与该类型相关的选项数组。

我已经建立了一个方法来在我的插件数组中创建一个新的插件,它有两个输入,一个是名称是一个标准控件,采用一个字符串,另一个是一个嵌套在这个对象中的数组,其中包括与该类型相关的所有插件选项.

我能够在该插件对象中添加一个新的插件和插件选项,但是当尝试更新这些嵌套选项的值时,我无法将 formControlName 附加到我需要更新它们的值的每个选项。

我不断收到以下错误以供参考:

vendor.js:63956 ERROR 错误:找不到路径控制:'addons -> 0 -> 0 -> option

创建新选项时,我不确定如何给它一个唯一的表单控件名称,以便更新它的值。任何输入将不胜感激。

下面是我的代码

主要形式:

menuForm = this.builder.group({
  name: this.builder.control<string>('', Validators.required),
  price: this.builder.control<string>('', Validators.required),
  description: this.builder.control<string>('', Validators.required),
  itemType: this.builder.control<string>('', Validators.required),
  image: this.builder.control<NonNullable<any>>('', Validators.required),
  imageName: this.builder.control<string>('', Validators.required),
  categories: this.builder.array([]),
  relatedsides: this.builder.array([]),
  addons: this.builder.array([]),
});

添加新插件和添加新插件选项的方法:

addAddon() {
  const addOnForm = this.builder.group({
    addonname: ['', Validators.required],
    addonoptions: this.builder.array([]),
  });
    
  this.addons.push(addOnForm);
}
    
addAddonOption(i: number) {
  const addOnOptionForm = this.builder.group({
    option: this.builder.control<string>(''),
  });
    
  this.addons.value[i].addonoptions.push(addOnOptionForm);
    
  console.log('addons with options', this.addons.value);
}

HTML:

 <!-- Addons Array -->

      <ng-container type="form" formArrayName="addons">
        <h4>Add Addons</h4>
        <ng-container *ngFor="let addOnForm of addons.controls; let x = index">
          <div [formGroupName]="x" class="addons-form-row">
            <mat-form-field appearance="fill">
              <input matInput placeholder="Addon" formControlName="addonname" />
            </mat-form-field>

            <button type="button" (click)="deleteAddOn(x)">Delete Addon</button>
            <button type="button" (click)="addAddonOption(x)">
              add addon option
            </button>

            <ng-container
              *ngFor="
                let addonoption of addons.value[x].addonoptions;
                let k = index
              "
            >
              <div [formGroupName]="k" class="imbeded-addon-options">
                <mat-form-field appearance="fill">
                  <input
                    matInput
                    type="text"
                    placeholder="Add On Option"
                    formControlName="option"
                  />
                </mat-form-field>
              </div>
            </ng-container>
          </div>
        </ng-container>
      </ng-container>
      <div>
        <button type="button" (click)="addAddon()">Add Addon</button>
      </div>
angular typescript angular-reactive-forms angular-forms formarray
1个回答
1
投票

你的

FormGroup
从根形式到
option
控制的结构应该是:

FormGroup

-->

addons
FormArray

--> addon 的索引

FormGroup

-->

addonoptions
FormArray

--> addonoption

FormGroup

的索引

-->

option
FormControl


  1. 错过

    formArrayName="addonoptions"
    模板。

  2. 修改从

    addonoptions
    FormArray
    .
    迭代
    addon
    FormGroup

    的方式
<ng-container formArrayName="addonoptions">
  <ng-container
    *ngFor="
      let addonoption of addonoptions(x).controls;
      let k = index
    "
  >
    <div [formGroupName]="k" class="imbeded-addon-options">
      <mat-form-field appearance="fill">
        <input
          matInput
          type="text"
          placeholder="Add On Option"
          formControlName="option"
        />
      </mat-form-field>
    </div> 
  </ng-container>
</ng-container>
addAddonOption(i: number) {
  const addOnOptionForm = this.builder.group({
    option: this.builder.control<string>(''),
  });

  this.addonoptions(i).push(addOnOptionForm);

  console.log('addons with options', this.addons.value);
}

addonoptions(addonFormIndex: number): FormArray {
  return (this.addons.get(`${addonFormIndex}`) as FormGroup).controls
    .addonoptions as FormArray;
}

Demo @ StackBlitz

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