首页 文章

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

提问于
浏览
1

在我使用反应式表单的Angular 7应用程序中,我正在基于 *ngFor 循环创建 input 元素,因此我最终得到一个动态命名的输入:

<nav class="level" *ngFor="let work of workLeft">
    <input [formControlName]="work.abbrev">

这当然工作正常,但现在我正在尝试将验证错误消息添加到表单,但我不知道如何“解决”该项目 . 例如,div通常看起来像这样:

<div *ngIf="name.errors.required">

但我没有 name ,因为它是动态的 work.abbrev 值 . 处理这个问题的正确方法是什么?

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

1 回答

  • 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: I 've made a few updates to the StackBlitz that you' ve共享包括Angular Style Guide推荐的内容以及实际解决方案 . 希望有所帮助 .

相关问题