使用动态命名控件进行角反应式表单验证

时间:2018-11-20 19:52:31

标签: angular angular-reactive-forms angular7 angular2-form-validation

在我的使用反应形式的Angular 7应用程序中,我基于class SomeClass extends CActiveRecord { public $dateAmount; ... } 循环创建enter code here a:17:{s:12:"cfdb7_status";s:4:"read";s:10:"user_login";s:5:"MyUser";s:4:"Date";s:10:"2018-11-20";s:10:"Name";s:3:"ABC";s:2:"BS";a:1:{i:0;s:1:"B";}s:3:"CMP";s:4:"1200";s:3:"CAB";a:1:{i:0;s:2:"CM";}s:2:"T1";s:3:"200";s:2:"T2";s:0:"";s:2:"T3";s:0:"";s:2:"SL";s:3:"150";s:8:"Calendar";a:1:{i:0;s:2:"TF";}s:8:"Period1C";s:0:"";s:8:"Period2C";s:0:"";s:2:"P1";s:1:"3";s:2:"P2";s:1:"6";s:8:"TimeType";a:1:{i:0;s:1:"M";}} 元素,因此最终得到一个动态命名的输入:

input

这当然可以正常工作,但是现在我试图将验证错误消息添加到表单中,但是我不确定如何“解决”该项目。例如,div通常看起来像这样:

*ngFor

但是我那里没有<nav class="level" *ngFor="let work of workLeft"> <input [formControlName]="work.abbrev"> ,因为它是动态的<div *ngIf="name.errors.required"> 值。处理这个问题的正确方法是什么?

您可以在这里看到我的尝试:https://stackblitz.com/edit/angular-8zevc1

1 个答案:

答案 0 :(得分:0)

我建议为此使用FormArray。使用FormArray,您的实现将如下所示:

对于组件类:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';

export interface Data {
  abbrev: string;
  max: number;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  workForm: FormGroup;
  workLeft: any[];

  constructor(private fb: FormBuilder) {}

  ngOnInit () {

    this.workForm = this.fb.group({
      points: this.fb.array([])
    });

    this.fillFormArray();
  }

  private fakeWebserviceCall(): Data[] {
    return [
      { abbrev: 'foo', max: 12 },
      { abbrev: 'bar', max: 10 }
    ];
  }

  private fillFormArray() {
    this.workLeft = this.fakeWebserviceCall();
    const formControlsArray = this.workLeft.map(work => this.fb.control(work.abbrev, [Validators.min(0), Validators.max(work.max)]));
    formControlsArray.forEach(control => this.points.push(control));
    console.log(this.workForm.value);
  }

  get points(): FormArray {
    return <FormArray>this.workForm.get('points');
  }

  pointAt(index) {
    return (<FormArray>this.workForm.get('points')).at(index);
  }

}

在模板中:

<form [formGroup]="workForm">
    <div formArrayName="points">
        <div *ngFor="let point of points.controls; let i = index">
      {{ workLeft[i].abbrev }}: <input type="number" [formControlName]="i">
      <div *ngIf="pointAt(i).invalid && (pointAt(i).dirty || pointAt(i).touched)">
        The field is invalid
      </div>
    </div>
  </div>
</form>

这是您推荐的Sample StackBlitz

PS:我对您共享的StackBlitz进行了一些更新,其中包括《 Angular Style Guide》推荐的内容以及实际解决方案。希望有帮助。