简体   繁体   English

从反应形式角度中的元素自动创建FormControls

[英]Auto Create FormControls from elements in Reactive Forms Angular

As you know when we create forms with Reactive Forms in Angular we assign formcontrolname to elements and also manually create formcontrols like below: 如您所知,当我们使用Angular中的“反应式表单”创建表单时,我们将formcontrolname分配给元素,并手动创建如下形式的formcontrol:

<form   [formGroup]="ntForm" (change)="onChange($event)" (ngSubmit)="onSubmit()" class="nt-form">
  <mat-form-field class="example-full-width">
    <input  matInput placeholder="User Id" formControlName="userId" [min]="5">
    <mat-error >{{getErrors('userId')}}</mat-error>
  </mat-form-field>

  <mat-form-field class="example-full-width">
    <input matInput placeholder="Id"  formControlName="id" required [min]="10">
    <mat-error >{{getErrors('id')}}</mat-error>
  </mat-form-field>

  <mat-form-field class="example-full-width">
    <input matInput placeholder="Title" formControlName="title" [email]="true">
    <mat-error >{{getErrors('title')}}</mat-error>
  </mat-form-field>

  <button class="nt-form-button" type="submit">Submit</button>

Manually adding formcontrols: 手动添加表单控件:

 this.ntForm = this.form.group({
      'id': new FormControl('id'),
      'userId': new FormControl('userId'),
      'title': new FormControl('title')   
    });

This may seems simple at first but what about if we have 20 elements? 乍一看这似乎很简单,但是如果我们有20个元素呢? We need to manually add names and maintain them. 我们需要手动添加名称并进行维护。 In Agile development it will be pain. 在敏捷开发中,这将是痛苦的。 To solve this I create a function which auto create controls based on formControlName attribute: 为了解决这个问题,我创建了一个基于formControlName属性自动创建控件的函数:

 fillControls(data) {
    const els: any = document.getElementsByClassName('nt-form')[0]
      .querySelectorAll('[formControlName]');
    els.forEach(node => {
      const controlName = node.attributes['formcontrolname'].nodeValue;
      this.ntForm.addControl(controlName, new FormControl('', []));
    });
  }

But with this approach errors will be emitted stating ('Cannot find control with name: '') because I firstly initialize form with empty controls and them fill it. 但是使用这种方法会发出错误,指出错误(“找不到名称为''的控件),因为我首先使用空控件初始化表单并将其填充。 How can I solve this problem? 我怎么解决这个问题? thanks 谢谢

In my opinion, you're doing it wrong. 我认为您做错了。

Instead of getting the control names from HTML, you should get it from the TS and iterate over it from the HTML. 与其从HTML中获取控件名称,不如从TS中获取控件名称,并从HTML中对其进行迭代。

For instance, you could use an interface to create form controls, use a static method to create a form group from it, and iterate over the interfaced elements in your HTML. 例如,您可以使用界面创建表单控件,使用静态方法从中创建表单组,然后遍历HTML中的界面元素。

export interface ReactiveFormControl {
  name: string;
  placeholder: string;
  defaultValue: string;
  validators: Validators[];
}

export class ReactiveFormUtils {
  public static toFormGroup(builder: FormBuilder, controls: ReactiveFormControl[]) {
    const form = {};
    controls.forEach(control => form[control.name] = [control.defaultValue, [...control.validators]]);
    return builder.group(form);
  }

  public static getControlNames(controls: ReactiveFormControl[]) {
    return controls.map(control => control.name);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM