Добавление и удаление групп форм из массива форм - PullRequest
0 голосов
/ 09 июля 2019

Я создал угловую реактивную форму, которая имеет пару базовых элементов управления формой, а затем массив форм простых групп форм. Вы можете динамически добавлять и удалять экземпляры групп форм из массива форм.

Вот демоверсия .

Когда вы динамически добавляете новый экземпляр группы форм, его поля обязательны для заполнения. Тем не менее, вы можете удалить его. Поскольку поля обязательны для заполнения, форма становится недействительной сразу после добавления новой группы форм. Проблема, с которой я сталкиваюсь, заключается в том, что форма остается недействительной, даже если вы удалите экземпляр группы форм, и все оставшиеся элементы управления формой действительны. Я проверил это - я перебрал все свои элементы формы, и каждый отдельный элемент управления формы действителен, но массив форм остается недействительным.

Как я могу убедиться, что массив форм действителен после удаления из него недопустимой группы форм?

Компонентный

import { AbstractControl, FormArray, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms';

import {Component, OnInit } from '@angular/core';

/**
 * @title Inputs in a form
 */
@Component({
  selector: 'input-form-example',
  templateUrl: 'input-form-example.html',
  styleUrls: ['input-form-example.css'],
})
export class InputFormExample implements OnInit {

  studyGuideForm: FormGroup;
  error: string = null;

  constructor(
    private fb: FormBuilder
    ) { }

    ngOnInit() {
      this.studyGuideForm = this.fb.group({
        studyGuideName: ['', Validators.required],
        description: [''],
        flashCards: this.fb.array([
          this.fb.group({
            front: ['', Validators.required],
            back: ['', Validators.required]
          })
        ], this.invalidFlashCardValidator())
      });
  }

  onSubmit() {
    if (this.studyGuideForm.valid) {
      console.log("Validation successful, can create");
      this.error = null;
    } else {
      console.log("The form is invalid, cannot submit");
      this.error = "Please enter all required fields and try again.";
    }
  }

  get flashCards() {
    return this.studyGuideForm.get('flashCards') as FormArray;
  }


  addFlashCard() {
    this.flashCards.push(this.fb.group({ front: '', back: ''}));
  }

  isRemovable() {
    return this.flashCards.length > 1;
  }

  removeFlashCard(pos: number) {
    this.flashCards.controls.splice(pos, 1);
  }

  invalidFlashCardValidator(): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} | null => {
      if (this.studyGuideForm) {
        let flashCardControls = this.flashCards.controls;
        for (const control in flashCardControls) {
          let fg = flashCardControls[control] as FormGroup;
          if (!fg.valid) {
            return {'invalidFlashCard': { value: 'Invalid flash card detected'}};
          }
        }
      }
      return null;
    }
  }

}

Template

<mat-card class="card-container">
    <h1 class="center-text">Create Study Guide</h1>
    <form [formGroup]="studyGuideForm" class="form-primary">
        <h2>Basic Information</h2>
        <mat-form-field class="full-width">
          <input matInput placeholder="Name" formControlName="studyGuideName" name="name" required>
        </mat-form-field>
        <mat-form-field class="full-width">
          <textarea matInput placeholder="Description" formControlName="description" name="description"></textarea>
        </mat-form-field>
        <div formArrayName="flashCards">
            <h2>Flash Cards</h2>
            <div *ngFor="let flashCard of flashCards.controls; index as i; first as isFirst" class="flash-card full-width" appearance="outline">
                <div [formGroupName]="i">
                    <div *ngIf="isRemovable()" class="close" (click)="removeFlashCard(i)">X</div>
                    <mat-form-field class="full-width">
                        <textarea matInput placeholder="Front" formControlName="front" name="front{{i}}" required></textarea>
                    </mat-form-field>
                    <mat-form-field class="full-width">
                        <textarea matInput placeholder="Back" formControlName="back" name="back{{i}}" (keydown.Tab)="onTab(i)" required></textarea>
                    </mat-form-field>
                </div>
            </div>
            <button mat-fab color="accent" (click)="addFlashCard()" class="add-button">+</button>
        </div>
    </form>
</mat-card>
<div class="button-container">
    <button mat-raised-button color="primary" class="big-button" (click)="onSubmit()">Submit</button>    
</div>
<p class="error-text" *ngIf="error || (error && !studyGuideForm.valid)">{{ error }} </p>

1 Ответ

2 голосов
/ 09 июля 2019

просто обновить состояние достоверности массива форм вручную, используя updateValueAndValidity метод AbstractControl

  removeFlashCard(pos: number) {
    this.flashCards.controls.splice(pos, 1);
    this.flashCards.updateValueAndValidity();
  }

на основе комментария @ Eliseo, лучше использовать removeAt() метод FormArray

  removeFlashCard(pos: number) {
    this.flashCards.removeAt(pos);
  }
...