动态角度的FormArray

问题描述

我已经实现了stackblitz,您可以在其中使用某些配置来创建动态表单。一切正常,直到您使用model1 = clm(IC~AU+CU+IUe,data = control,link = "logit") summary(model1) 。有什么想法基本上,您的配置文件中可以有许多不同类型的字段。例如model1<-lmList(IC ~ B + D + E | Participant,data=control,family=binomial(link="logit")) model1 FormArraycheckBox text等。在某些情况下,您应具有更复杂的结构,因此应具有number在这次堆叠闪电战中,我试图代表正在发生的事情

https://stackblitz.com/edit/angular-dynamic-form-builder-gycshd?file=app/dynamic-form-builder/dynamic-form-builder.component.ts

因此,当我找到一个select类型时,我将创建一个FormArray而不是简单的FormArray,这是我的字段列表

array

这是我的动态表单构建器组件

FormControl

如您所见,我从allDatas中设置了一个值(如果存在),并使用FormControls和FormArray创建了FormGroup。但是,当我生成 public fields: any[] = [ { type: "text",name: "firstName",label: "First Name",required: true },{ type: "text",name: "lastName",label: "Last Name",name: "email",label: "Email",name: "description",label: "Description",required: true,multiLine: true },{ type: "dropdown",name: "country",label: "Country",value: "in",options: [{ value: "in",label: "India" },{ value: "us",label: "USA" }] },{ type: "array",name: "users",label: "Users",structure: "users.json" } ]; 时会出错。这是显示FormArray控件的arrayBox组件:

export class DynamicFormBuilderComponent implements OnInit {
  @Output() onSubmit = new EventEmitter();
  @input() fields: any[] = [];
  form: FormGroup;
  allDatas: any;
  constructor() {}

  ngOnInit() {
    let fieldsCtrls = {};
    this.allDatas = getData();
    for (let f of this.fields) {
      if (f.type != "array") {
        fieldsCtrls[f.name] = new FormControl(
          this.allDatas[f.name] || "",Validators.required
        );
      } else {
        fieldsCtrls[f.name] = new FormArray([
          new FormControl(this.allDatas[f.name] || "",Validators.required)
        ]);
      }
    }
    this.form = new FormGroup(fieldsCtrls);
  }
}

getData()返回该FormArray的结构。在这种情况下

arrayBox

控制台中的错误是:

import { HttpClient } from "@angular/common/http";
import { Component,Input,OnInit } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { ConfigService } from "../../config.service";

@Component({
  selector: "arrayBox",template: `
    <div [formGroup]="form">
      <div formArrayName="{{ field.name }}">
        <div
          *ngFor="let obj of arrayFileds; index as idx"
          [formGroupName]="idx"
        >
          <input
            attr.type="{{ obj.type }}"
            class="form-control"
            placeholder="{{ obj.name }}"
            id="{{ obj.name }}"
            name="{{ obj.name }}"
            formControlName="{{ idx }}"
          />
        </div>
      </div>
    </div>
  `
})
export class ArrayBoxComponent implements OnInit {
  @input() field: any = {};
  @input() form: FormGroup;
  arrayFileds: any = [];

  get isValid() {
    return this.form.controls[this.field.name].valid;
  }
  get isDirty() {
    return this.form.controls[this.field.name].dirty;
  }

  constructor(private config: ConfigService) {}

  ngOnInit(): void {
    this.arrayFileds = this.config.getData(this.field.structure);
    console.log(this.arrayFileds);
  }
}

我真的不知道这是怎么回事。如何使用FormArray以这种形式显示字段及其值?

NB。如果我使用http解析json,stackblitz会给我一个错误,所以现在我直接使用json的导入。基本上,此示例中未使用[{ "label": "Username","name": "userName","type": "text" },{ "label": "User email","name": "userEmail","type": "text" }] (但应该使用)。

解决方法

很好,但是您需要更改一些内容才能实现所需的功能。

  1. 您需要更改初始化表单数组的方式。您已经在# this refitting is actually not needed. it is simply here for having separate models... manual_svr_new = SVR(kernel='rbf',gamma=gamma_space,C=C_space,epsilon=epsilon_space).fit(x_train_scaled,y_train) y_pred_manual_new = manual_svr_new.predict(x_test_scaled_new) error_manual_new = mean_absolute_error(y_pred_manual_new,y_test) # And test it: error_manual_new == error # Out: True 中命名了控件,因此需要将FormArray推入FormGroup中:
FormArray

上面的代码基本上生成 for (let f of this.fields) { if (f.type != "array") { fieldsCtrls[f.name] = new FormControl( this.allDatas[f.name] || "",Validators.required ); } else { // changed part fieldsCtrls[f.name] = new FormArray([ ...this.allDatas[f.name].map( r => new FormGroup( Object.entries(r).reduce((acc,[k,v]) => { acc[k] = new FormControl(v || "",Validators.required); return acc; },{}) ) ) ]); } ,其对象键为FormGroup

  1. 您需要像下面这样更改FormControls组件模板:
ArrayBox

您有 <input attr.type="{{ obj.type }}" class="form-control" placeholder="{{ obj.name }}" id="{{ obj.name }}" name="{{ obj.name }}" formControlName="{{ obj.name }}" /> ,这将导致Angular寻找名为formControlName="{{ idx }}"的{​​{1}},这是您收到FormControl错误的原因之一。另一个原因是您直接添加了0 1而不是Error: Cannot find control with path: 'users -> 0 -> 0'。由于您的FormControl模板状态FormGroup具有一个ArrayBox

数组

Working Stackblitz

@ End.Game注意到数组部分仍有一些部分需要修复。问题的根本原因在于FormArray模板。您正在遍历配置对象以呈现表单。但是由于它是FormGroup,所以您还需要重复该模板来计算ArrayBox的数量。因此,您将需要另一个FormArray来实现:

FormArray

还请注意,将*ngFor变量移至了父循环。

,

请查看以下stackblitz示例:-

https://stackblitz.com/edit/angular-dynamic-form-creation

希望对您有用!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...