代码之家  ›  专栏  ›  技术社区  ›  Gargoyle

带有动态命名控件的角度反应形式验证

  •  2
  • Gargoyle  · 技术社区  · 6 年前

    在我的Angular7应用程序中,使用我正在创建的反应式表单 input 基于 *ngFor 循环,因此我以一个动态命名的输入结尾:

    <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 回复  |  直到 6 年前
        1
  •  0
  •   SiddAjmera    6 年前

    我建议使用 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样式指南推荐的内容以及实际的解决方案。希望有帮助。

    推荐文章