J'ai un formulaire réactif avec le champ de saisie dynamique. J'ai généré ces champs avec FormArray
. Maintenant, j'essaie de préremplir le formulaire avec des données sur l'écran d'édition, mais je n'ai pas pu le faire. J'ai essayé de remplir en utilisant la méthode setControl
J'ai eu cette erreur Impossible de trouver le contrôle avec le chemin: 'books -> 0 -> name'
Voici les sources que j'ai prises pour référence
<form [formGroup]="formGroup"> <div formArrayName="books" *ngFor="let book of formGroup.get('books')['controls']; let i = index;"> <div class="row" [formGroupName]="i"> <input type="text" autocomplete="off" placeholder="*Name" formControlName="name"> <input type="text" autocomplete="off" placeholder="*Author" formControlName="author"> <button type="button" class="btn btn-success" (click)="addBook();">Add</button> </div> </div> </form>
import { Component } from '@angular/core'; import { FormBuilder, FormGroup, FormArray } from '@angular/forms'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; export interface ServerResponse { books: any; } @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { formGroup: FormGroup; books: FormArray; constructor( private http: HttpClient, private formBuilder: FormBuilder, ) { } createForm() { this.formGroup = this.formBuilder.group({ books: this.formBuilder.array([this.createBookForm()]), }); } createBookForm() { return this.formBuilder.group({ name: [], author: [], }); } addBook() { this.books = this.formGroup.get('books') as FormArray; this.books.push(this.createBookForm()); } getData(): Observable<ServerResponse> { return this.http.get<ServerResponse>('https://demo0331989.mockable.io/library/data/book'); } populateData() { this.getData().subscribe(data => { this.formGroup.setControl('books', this.formBuilder.array(data.books || [])); }); } ngOnInit() { this.createForm(); this.populateData(); } }
Je partage également le code dans Stackblitz . Échantillon / simulation de données à pré-remplir. Je ne suis pas sûr de ce qui me manque ici!
3 Réponses :
J'ai fait un fork de votre exemple stackblitz , alors jetez un œil. Lorsque vous souhaitez pré-remplir votre formulaire, vous devez créer BookForm et le passer dans setControl, pas seulement dans un tableau.
lorsque vous remplissez un tableau de formulaire, vous devez le remplir avec des groupes de formulaires remplis, de sorte que cela ressemble à ceci:
populateData() { this.getData().subscribe(data => { const books = this.formGroup.get('books') as FormArray; // get the array books.clear(); // clear the array data.books.forEach(b => { // iterate data let fg = this.createBookForm(); // create the group fg.reset(b); // fill the data books.push(fg); // add to array }); this.addBook(); // add blank form to end if desired }); }
la suppression de la partie du formulaire / l'ajout du blanc au end peut ou non être nécessaire.
voici un blitz fixe: https://stackblitz.com/edit/angular-9ts4yv?file=src/app/app.component.ts
avertissement cette réponse est complémentaire de la réponse @ bryan60,
J'aime ma fonction createBookForm a comme argument "data", donc
populateData() { this.getData().subscribe(data => { const books = this.formGroup.get('books') as FormArray; books.clear(); data.books.forEach(b => { books.push(this.createBookForm(b)) }); }); }
Cela nous permet d'écrire
createBookForm(null) //create a FormGroup with name and author and values null //or createBookForm({name:"Linus Administration",author:"Roger"}) //the formgroup has values
Notre fonction populateData devient plus simple
createBookForm(data:any) { data=data||{name:null,author:null} return this.formBuilder.group({ name: data.name, author: data.author, }); }
REMARQUE: je ne vois pas le nécésité de déclarer un formGroup avec une propriété unique qui est un FormArray, voir ma réponse entre autres dans question stackoverflow
Ça marche! Eh bien, explication claire. Merci.