[Angular] Update FormArray with patchValue
阿新 • • 發佈:2017-08-17
strategy ror ont edi code gre sts sha button
Currently, patchValue doesn‘t support update FormArray.
The workarround is you need to empty the form array first, then add items back.
import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges} from ‘@angular/core‘; import {FormBuilder, FormArray, FormGroup, FormControl, Validators}from ‘@angular/forms‘; import {Meal} from ‘../../../shared/services/meals/meals.service‘; @Component({ selector: ‘meal-form‘, changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: [‘meal-form.component.scss‘], template: ` <div class="meal-form"> <form [formGroup]="form"> <div class="meal-form__name"> <label> <h3>Meal name</h3> <input type="text" formControlName="name" placeholder="e.g. English Breakfast"> <div class="error" *ngIf="required"> Workout name is required </div> </label> </div> <div class="meal-form__food"> <div class="meal-form__subtitle"> <h3>Food</h3> <button type="button" (click)="addIngredient()" class="meal-form__add"> <img src="/img/add-white.svg" alt="Add food"> Add food </button> </div> <div formArrayName="ingredients"> <label *ngFor="let c of ingredients.controls; index as i;"> <input type="text" [formControlName]="i" placeholder="e.g Eggs"> <span class="meal-form__remove" (click)="removeIngredient(i)" ></span> </label> </div> <div class="meal-form__submit"> <div> <button *ngIf="!exists" type="button" class="button" (click)="createMeal()"> Create Meal </button> <button *ngIf="exists" type="button" class="button" (click)="updateMeal()"> Save </button> <a [routerLink]="[‘../‘]" class="button button--cancel"> Cancel </a> </div> <div class="meal-form__delete" *ngIf="exists"> <div *ngIf="toggled"> <p>Delete item?</p> <button class="confirm" type="button" (click)="removeMeal()"> Yes </button> <button class="cancel" type="button" (click)="toggle()"> No </button> </div> <button class="button button--delete" type="button" (click)="toggle()"> Delete </button> </div> </div> </div> </form> </div> ` }) export class MealFormComponent implements OnChanges { toggled = false; exists = false; @Input() meal: Meal; @Output() create = new EventEmitter<Meal>(); @Output() update = new EventEmitter<Meal>(); @Output() remove = new EventEmitter<Meal>(); form = this.fb.group({ name: [‘‘, Validators.required], ingredients: this.fb.array([‘‘]) }); get ingredients() { // Type check for ingredients, mark as FormArray // Therefore when we use ‘ingredients‘, // We can get auto complete return this.form.get(‘ingredients‘) as FormArray; } get required() { return ( this.form.get(‘name‘).hasError(‘required‘) && this.form.get(‘name‘).touched ); } constructor(private fb: FormBuilder) { } ngOnChanges(changes: SimpleChanges): void { if (this.meal && this.meal.name) { this.exists = true; this.emptyIngredients(); const value = this.meal; this.form.patchValue(value); if (value.ingredients) { for (const item of value.ingredients) { this.ingredients.push(new FormControl(item)); } } } } emptyIngredients() { while (this.ingredients.controls.length > 0) { this.ingredients.removeAt(0); } } createMeal() { if (this.form.valid) { this.create.emit(this.form.value); } } updateMeal() { if (this.form.valid) { this.update.emit(this.form.value); } } removeMeal() { this.remove.emit(this.form.value); } addIngredient() { // Add a new FormControl to FormArray this.ingredients.push(new FormControl(‘‘)); } removeIngredient(i: number) { this.ingredients.removeAt(i); } toggle() { this.toggled = !this.toggled; } }
[Angular] Update FormArray with patchValue