Реактивная форма говорит, что она недействительна, когда новая FormGroup добавляется в FormArray, когда она действительна

У меня есть реактивная форма для создания рецепта с тремя элементами управления:

  • Заголовок
  • An FormArray of a FormGroup of ingredients which have two properties
    • The name of the ingredient
    • Сумма взята
  • FormArray шагов

Моя проблема в том, что всякий раз, когда я добавляю FormControl или FormGroup в FormArray, статус формы недействителен, даже если я заполняю все поля. Есть кнопка отправки, которая становится недоступной, если форма недействительна.

Мой код:

<h1>Create a recipe</h1>

<form [formGroup]="recipe" (ngSubmit)="onSubmit()" autocomplete="off">
    <div>
        <mat-form-field appearance="outline" color="accent" hideRequiredMarker="true">
            <mat-label>Name</mat-label>
            <input formControlName="title" matInput required type="text" placeholder="ex. Oats Smoothie">
            <mat-error>Name is <strong>required</strong></mat-error>
        </mat-form-field>
    </div>
    <hr>
    <div formArrayName="ingredients">
        <div *ngFor="let control of ingredients.controls; index as i">
            <div [formGroupName]="i">
                <mat-form-field appearance="outline" color="accent" hideRequiredMarker="true">
                    <mat-label>Ingredient name</mat-label>
                    <input formControlName="name" matInput required placeholder="ex. Oats" type="text">
                    <mat-error>Ingredients are
                        <strong>required</strong>
                    </mat-error>
                </mat-form-field>
                <mat-form-field appearance="outline" color="accent" hideRequiredMarker="true">
                    <mat-label>Ingredient amount</mat-label>
                    <input formControlName="amount" matInput type="text" placeholder="ex. 1 cup">
                    <mat-error>Ingredients are
                        <strong>required</strong>
                    </mat-error>
                    <mat-icon matSuffix (click)="removeIngredient(i)" *ngIf="!(ingredients.controls.length == 1)">clear</mat-icon>
                </mat-form-field>
            </div>
        </div>
        <button type="button" mat-raised-button color="primary" (click)="addIngredient()">Add Ingredient</button>
    </div>
    <hr>
    <div formArrayName="steps">
        <mat-form-field *ngFor="let step of steps.controls; index as i" appearance="outline" color="accent"
            hideRequiredMarker="true">
            <mat-label>Steps</mat-label>
            <textarea [formControlName]="i" type="text" matInput placeholder="ex. Take Oats"
                cdkTextareaAutosize></textarea>
            <mat-icon matSuffix (click)="removeStep(i)" *ngIf="!(steps.controls.length == 1)">clear</mat-icon>
            <mat-error>Steps are <strong>required</strong></mat-error>
        </mat-form-field>
        <br>
        <button type="button" (click)="addStep()" mat-raised-button color="primary">Add Step</button>
    </div>
    <br>
    <button type="submit" [disabled]="!recipe.valid" mat-raised-button color="primary">Submit</button>
</form>
  recipe: FormGroup | any;
  constructor(private formBuilder: FormBuilder, private recipeService: RecipesService, private dialog: MatDialog, private router: Router) { }

  ngOnInit(): void {
    this.recipe = this.formBuilder.group({
      title: ['', Validators.required],
      ingredients: this.formBuilder.array([
        this.formBuilder.group({
          name: ['', Validators.required],
          amount: ['', Validators.required]
        })
      ]),
      steps: this.formBuilder.array([
        this.formBuilder.control('', Validators.required)
      ])
    });
  }

  onSubmit() {
    this.recipeService.createRecipe(this.recipe.value.title, this.recipe.value.ingredients, this.recipe.value.steps).subscribe();
  }

  get steps() {
    return this.recipe.get('steps') as FormArray;
  }

  addStep() {
    this.steps.push(this.formBuilder.control('', Validators.required));
  }

  get ingredients() {
    return this.recipe.get('ingredients') as FormArray;
  }

  addIngredient() {
    this.ingredients.push(this.formBuilder.group({ name: ['', Validators.required], amount: ['', Validators.required, Validators.pattern(/^\d\s?\w+/g)] }));
    this.recipe.valid = this.recipe.valid ? !this.recipe.valid : this.recipe.valid;
  }

person Community    schedule 05.01.2021    source источник
comment
попробовать позвонить this.recipe.updateValueAndValidity() после добавления нового элемента?   -  person Ashot Aleqsanyan    schedule 05.01.2021
comment
Это работает @Ashot! Если вы дадите ответ, я приму его.   -  person    schedule 05.01.2021
comment
вы можете добавить его по своему усмотрению и принять его, без проблем. Главное, чтобы проблема решена ;-)   -  person Ashot Aleqsanyan    schedule 05.01.2021


Ответы (1)


Я решил это, добавив this.recipe.updateValueAndValidity, как указано @Ashot, в функции addStep и addIngredient

person Community    schedule 05.01.2021