【问题标题】:Auto Create FormControls from elements in Reactive Forms Angular从反应式表单Angular中的元素自动创建FormControls
【发布时间】:2019-01-15 08:09:04
【问题描述】:

如您所知,当我们在 Angular 中使用响应式表单创建表单时,我们将 formcontrolname 分配给元素,并手动创建如下所示的表单控件:

<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>

手动添加表单控件:

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

一开始这似乎很简单,但如果我们有 20 个元素呢? 我们需要手动添加名称并维护它们。在敏捷开发中,这将是痛苦的。 为了解决这个问题,我创建了一个基于 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('', []));
    });
  }

但是使用这种方法会发出错误说明('找不到具有名称的控件:''),因为我首先使用空控件初始化表单并填充它。 我怎么解决这个问题?谢谢

【问题讨论】:

  • 你为什么在角度使用 document.getElementsByClassName
  • 因为我只想查询指定类的表单元素。
  • 在角度你可以使用元素参考选择元素
  • 是的,代码可以稍后优化,但现在需要解决当前的问题。
  • 你想用动态数据创建表单吗?

标签: angular angular-reactive-forms angular-forms


【解决方案1】:

在我看来,你做错了。

您应该从 TS 中获取它并从 HTML 中迭代它,而不是从 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);
  }
}

【讨论】:

  • 您好,谢谢,但是如果没有 formControlName,form 中的元素如何绑定到 formGroup?
  • 它们会有一个表单控件名称,你只需要遍历它并使用 name 属性
  • 但是通过这个解决方案,我在 html 端和 ts 端创建了两次名称。所以这就像创建通常的反应形式。你能提供样品吗?谢谢
  • 不,你没有......你只需在 HTML &lt;input type="text" *ngFor="let control of controls" [formControlName]="control.name"&gt; 中使用循环。
  • 但这仅适用于相同的元素,例如输入。如果表单是混合输入、选择、复选框等的混合顺序怎么办?
猜你喜欢
  • 2021-02-08
  • 1970-01-01
  • 2018-05-31
  • 2019-06-21
  • 2019-05-31
  • 2018-02-12
  • 1970-01-01
  • 2019-06-08
  • 2019-02-01
相关资源
最近更新 更多