使用 Angular Reactive Form 启用 x 数量的预填充表单数组控件

Enabling x number of prepopulated form array controls with Angular Reactive Form

正在使用 Angular 和反应式表单生成器创建应用程序。

StackBlitz example

表单已预先填充,在表单中我使用 form.array 根据数据构建动态控件列表。我禁用了这些字段,因为我希望我的表单最初是只读的。我有一个在控件上触发 .enable 的按钮,但是作为 form.array 中的动态控件,我不确定如何在不指定所有控件索引值的情况下启用它们。

ts 文件

  public createForm() {
    this.service.getmodel().subscribe((response) => {
      this.model = response;

      this.form = this.fb.group({
        type: new FormControl({ value: null, disabled: !this.isOwner }),
        items: this.fb.array(
          this.model.items.map((x) =>
            this.buildFields(x)
          )
        ),
      });
    });
  }

  buildFields(x: any): FormGroup {
    return new FormGroup({
      name: new FormControl({ value: x.name, disabled: !this.isOwner }),
      description: new FormControl({
        value: x.description,
        disabled: !this.isOwner,
      }),
      code: new FormControl({ value: x.code, disabled: !this.isOwner }),
    });
  }

  enable() {
    this.isOwner = true;
    const controls = ['type', 'items.description'];
    controls.map((x) => {
      this.form.get(x).enable({ onlySelf: true });
    });
  }

我正在启用启用文本输入字段的控件“类型”,对于 form.array 中的项目,我刚刚添加了“items.description”- 虽然我知道这是不正确的值不存在。它类似于“items[0].description”,但 [0] 可以是由数据长度决定的任何值。

html 文件

<div *ngIf="form">
  <form [formGroup]="form">
    <textarea
      formControlName="type"
      name="type"
      #type
      class="form-control"
      id="type"
      rows="6"
    ></textarea>
    <div formArrayName="items">
      <div
        *ngFor="let orgs of form.controls['items']?.controls; let i = index"
        [formGroupName]="i"
      >
        <input formControlName="name" placeholder="Item name" />
        <input formControlName="description" placeholder="Item description" />
        <input formControlName="code" placeholder="Item price" />
      </div>
      <button type="button" class="btn btn-success" (click)="enable()">
      Enable
    </button>

    </div>
  </form>

  <!-- <p>{{ form.value.items}}</p> -->
</div>

最终目标是启用 formControlName="name/description/code"

StackBlitz example

如果我理解正确的话,你成功启用了“类型”但未能启用 name/description/code。

请记住,您的主 FormGroup 不包含任何 name/description/code,它包含另一个名为 items 的 FormGroup,其中包含您的控件。先从主窗体中获取子窗体组,然后就可以访问窗体控件​​了

将启用替换为:

  enable() {
    this.isOwner = true;
    this.form.get('type').enable({ onlySelf: true });
    let items = this.form.get('items') as FormArray;
    items.controls.forEach(c => {
      c.enable({onlySelf: true});
    })