web-dev-qa-db-fra.com

Angular 4 patchValue basé sur l'index dans FormArray

Je cherche à mettre à jour un formArray après que l'utilisateur a ajouté une valeur dans un contrôle créé vide.

Actuellement, lorsque l'utilisateur choisit d'ajouter un nouvel élément, je crée sur le formArray avec des valeurs vides.

buildItem(item?: any, key?: any): FormGroup {
  // Item will pass undefined for initial buildItem in onLoad and new items
  let itemName: string;
  let keyValue: string;
  if (item === undefined) { 
     itemName = ''; key = '' }  
  else { 
     itemName = item.name; keyValue = key 
  };

  /**
   * Builds a single item for form group array in the collectionForm.
   */
   return this.formBuilder.group({ 
                item: [itemName || '', Validators.required], 
                properties: { item, key: key } || {} });
}

Cela fonctionne bien pour la création initiale et la mise à jour des éléments déjà ajoutés. Le problème vient des nouveaux éléments qui sont ajoutés avec des valeurs vides. Lorsque j'ajoute un nouvel élément, j'ai besoin d'ajouter la clé de retour de Firebase dans le properties.key

Dans la méthode d'enregistrement de ce nouvel élément, j'ai ajouté un patchValue

this.items.patchValue([{ 
         // item being returned from firebase promise
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}]);

Cependant, le patchValue ne fonctionne pas du tout. Lorsque j'essaie de mettre à jour cette nouvelle valeur, bien que les valeurs aient été enregistrées dans firebase, j'obtiens toujours un retour pour les valeurs vides ou les valeurs de sauvegarde définies sur la BuildItem() initiale et non les valeurs mises à jour dans le patchValue

Je vois sur la documentation angular FormArray que

Il accepte un tableau qui correspond à la structure du contrôle et fera de son mieux pour faire correspondre les valeurs aux contrôles corrects du groupe . REF

Cela signifie-t-il qu'il pourrait ou non mettre à jour cette valeur ... il fera tout son possible pour essayer? Je pense que si je peux ajouter l'index pour la valeur que je veux corriger, cela ne devrait pas du tout être un problème. comme avec la removeAt(idx)

Donc, si je peux écrire quelque chose comme

this.form.patchValue.atIndex(this.idx,[{ 
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}];

Mais je ne suis pas sûr que je puisse le faire .. bien sûr que ce n'est pas possible sous cette forme. Existe-t-il un moyen de cibler spécifiquement l'élément qui est corrigé dans un formArray ou est-ce que je ne comprends peut-être pas cela correctement.

Je peux en quelque sorte m'en tirer en poussant la nouvelle valeur sur le formArray

this.items.Push(this.buildItem(...));

mais je dois ajouter

this.items.removeAt(this.idx); 

Afin de supprimer le contrôle initial sur la construction vide, ce qui ne ressemble à aucune sorte de bon code.

20
user1752532

Utilisez FormArray#at + AbstractControl#patchValue :

this.items.at(index).patchValue(...);
22
developer033

Vous pouvez le faire simplement en créant un nouveau FormControl si vous souhaitez mettre à jour la structure du tableau de trous:

this.form.setControl('items',  new FormControl(arrayItemsValue));

Ou en supprimant tous les éléments avant de les mettre à jour:

const items = (<FormArray>this.form.get('items'));
 for (let i = 0; i < items.length; i++) {
     items.removeAt(i);
 }
 this.form.get('items').setValue(arrayItemsValue);
4
abahet