Угловая проверка реактивной формы с динамически именованными элементами управления - PullRequest
0 голосов
/ 20 ноября 2018

В моем приложении Angular 7, использующем реактивные формы, я создаю 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 Ответ

0 голосов
/ 21 ноября 2018

Я предлагаю использовать 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>

Вот Образец StackBlitz для вашей ссылки.

PS: Я сделал несколько обновлений для StackBlitz, которыми вы поделились, включая вещичто Angular Style Guide рекомендует вместе с фактическим решением.Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...