javascript - 无法使用此嵌套对象数组创建响应式(Reactive)表单

标签 javascript angular rxjs angular-reactive-forms form-control

我正在尝试创建一个具有复杂数据结构的响应式(Reactive)表单,该表单正在执行很多操作,我希望您帮助我了解如何创建它。所以基本上这是我想要使用的数据的结构:

[
  {
     type: 'body',
     items: [
        {
           type: 'text',
           id: 1,
           value: '',
           isCustom: false,
           customValue: '' 
        }
     ]
  }
]

items 数组中,可能有 0 或 100 万个项目。因此,如果至少有一个,我想在模板中显示字段。

所以基本上每个项目都有两个字段。一个是选择框,另一个是输入字段。选择框会有一些项目,我们只说一些选项。所有选项都是预定义的,当选择其中一个选项时,items 对象中的 value 字段将被存储。在选择框选项中,有是自定义选项之一。选择该选项后,value 字段将设置为 customisCustom 设置为 true,input 字段将设置为出现。当在 input 字段中输入内容时,customValue 字段将存储该内容。这是基本功能。

现在我可以做从更新、存储和验证等所有事情。除了我无法做第一件事,即设置表单控件。我想我必须在这里使用 Angular 的 FormArray 但我现在知道如何使用。

我需要您提供的只是如何根据我提供的数据结构创建此表单控件的简单说明。由于无法做到这一点,我从响应式(Reactive)表单转向了模板驱动表单,这让我对验证感到头疼。

这是我到目前为止尝试过的:

TS 文件:

private formBuilder = new FormBuilder();

form = this.formBuilder.group({
    title: new FormControl('', {
      validators: [
        Validators.required,
        FormValidator.nonWhitespace,
        Validators.maxLength(80),
      ],
    }),
    body: this.formBuilder.array([]),
});

ngOnInit(): void {
    if (this.bodyArray.controls.length === 0) {
      this.addBodyItem();
    }
}

get bodyArray(): FormArray {
    return this.form.get('body') as FormArray;
}

createBodyItem(): FormGroup {
    // no idea what to do here    
}

addBodyItem(): void {
    this.bodyArray.push(this.createBodyItem());
}

模板文件:

<div formArrayName="body">

   // no idea what to loop here

</div>

请注意,我在创建和编辑模式下使用相同的组件。因此,对于编辑模式,我认为需要在 ngOnInit 中创建表单控件来显示字段。

如果有人能帮助我解决这个问题,那将是非常大的帮助。

最佳答案

发布此信息供任何人引用。下面的代码示例动态生成表单控件,同时迭代提供的项目数组和基于它的属性。

app.component.ts:

import { Component,OnInit } from '@angular/core';
import {FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';
import * as uuid from 'uuid';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  implements OnInit{
  myForm: FormGroup;
  formControls = [
    { type: 'input', label: 'Name', name: 'name', inputType: 'text' },
    { type: 'input', label: 'Email', name: 'email', inputType: 'email' },
    { type: 'select', label: 'Country', name: 'country', options: [
        { label: 'United States', value: 'US' },
        { label: 'Canada', value: 'CA' },
        { label: 'Mexico', value: 'MX' }
      ]
    }
    // Add more form controls as needed
  ];
  constructor(private formBuilder: FormBuilder){}

  ngOnInit() {
    this.myForm = this.formBuilder.group({});
    this.formControls.forEach(control => {
      const formControl = new FormControl('', Validators.required); // Create form control
      this.myForm.addControl(control.name, formControl); // Add controls to myForm
    });
  }
 
}

app.component.html:

<form [formGroup]="myForm">
  <ng-container *ngFor="let control of formControls">
    <div [ngSwitch]="control.type">
      <div *ngSwitchCase="'input'">
        <label>{{ control.label }}</label>
        <input [formControlName]="control.name" [type]="control.inputType">
      </div>
      <div *ngSwitchCase="'select'">
        <label>{{ control.label }}</label>
        <select [formControlName]="control.name">
          <option *ngFor="let option of control.options" [value]="option.value">{{ option.label }}</option>
        </select>
      </div>
      <!-- Add more cases for other control types as needed -->
    </div>
  </ng-container>
</form>

请参阅示例工作 stackblitz here .

关于javascript - 无法使用此嵌套对象数组创建响应式(Reactive)表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76692871/

相关文章:

javascript - 如何从 AudioContext 元素收集时间值?

javascript - 简单的javascript问题(对我来说并不简单)

angular - 为什么我的 Angular 4 ChartJS 组件不呈现?

Angular - ngFor 和 trackBy 与异步管道

javascript - 如何在不使用已弃用的 retryWhen 的情况下延迟 RxJs 重试?

javascript - JavaScript 关联数组是如何工作的?

javascript - tinymce 例子中的 ed.onKeyDown

javascript - 由于 ɵɵinject 和 ɵɵdefineInjectable(在编译时出现错误),无法运行 Angular 应用程序

angular6:将输入字段的值传递给组件

angular - 如何将额外参数传递给 RxJS 映射运算符