web-dev-qa-db-fra.com

angular 2 supprime tous les éléments d'un formarray

J'ai un tableau de formulaire dans un formbuilder et je modifie les formulaires de manière dynamique, c'est-à-dire lorsque vous cliquez sur les données de chargement à partir de l'application 1, etc.

Le problème que j’ai, c’est que toutes les données sont chargées mais les données de la matrice restent et concattent les anciens éléments avec les nouveaux.

Comment puis-je effacer ce formarray pour n'avoir que les nouveaux éléments.

J'ai essayé ça

const control2 = <FormArray>this.registerForm.controls['other_Partners'];
        control2.setValue([]);

mais ça ne marche pas.

Des idées? Merci

en nginit

ngOnInit(): void {
this.route.params.subscribe(params => { alert(params['id']);
            if (params['id']) {
                this.id = Number.parseInt(params['id']);
            }
            else { this.id = null;}
          });
if (this.id != null && this.id != NaN) {
            alert(this.id);
            this.editApplication();
            this.getApplication(this.id);
        }
        else
        {
            this.newApplication();
        }

}

onSelect(Editedapplication: Application) {
 this.router.navigate(['/apply', Editedapplication.id]);
}

editApplication() {
      
        this.registerForm = this.formBuilder.group({
              id: null,
            type_of_proposal: ['', Validators.required],
            title: ['', [Validators.required, Validators.minLength(5)]],
            lead_teaching_fellow: ['', [Validators.required, Validators.minLength(5)]],
            description: ['', [Validators.required, Validators.minLength(5)]],
            status: '',
            userID: JSON.parse(localStorage.getItem('currentUser')).username,
            contactEmail: JSON.parse(localStorage.getItem('currentUser')).email,
            forename: JSON.parse(localStorage.getItem('currentUser')).firstname,
            surname: JSON.parse(localStorage.getItem('currentUser')).surname,
            line_manager_discussion: true,
            document_url: '',
            keywords: ['', [Validators.required, Validators.minLength(5)]],
            financial_Details: this.formBuilder.group({
                  id: null,
                buying_expertise_description: ['', [Validators.required, Validators.minLength(2)]],
                buying_expertise_cost: ['', [Validators.required]],
                buying_out_teaching_fellow_cost: ['', [Validators.required]],
                buying_out_teaching_fellow_desc: ['', [Validators.required, Validators.minLength(2)]],
                travel_desc: ['', [Validators.required, Validators.minLength(2)]],
                travel_cost: ['', [Validators.required]],
                conference_details_desc: ['', [Validators.required, Validators.minLength(2)]],
                conference_details_cost: ['', [Validators.required]],
            }),

            partners: this.formBuilder.array
                (
                [
                    //this.initEditPartner(),
                    //this.initEditPartner()
                    // this.initMultiplePartners(1)
                ]
                ),
            other_Partners: this.formBuilder.array([
                //this.initEditOther_Partners(),
            ])
           
        });
       
    }

getApplication(id)
    {
        

        this.applicationService.getAppById(id, JSON.parse(localStorage.getItem('currentUser')).username)
            .subscribe(Response => {
               
                    if (Response.json() == false) {
                        this.router.navigateByUrl('/');
                    }
                    else {
                        this.application = Response.json();  
                          for (var i = 0; i < this.application.partners.length;i++)
                          {
                                this.addPartner();
                          }
                          for (var i = 0; i < this.application.other_Partners.length; i++) {
                              this.addOther_Partner();
                          }

                          this.getDisabledStatus(Response.json().status);
                        (<FormGroup>this.registerForm)
                            .setValue(Response.json(), { onlySelf: true }); 
                      }

                }
         
        );

       
        
        

       
    }

ngonitit n'est pas appelé au clic

53
Karl O'Connor

J'ai eu le même problème. Il y a deux façons de résoudre ce problème.

Conserver l'abonnement

Vous pouvez effacer manuellement chaque élément FormArray en appelant la fonction removeAt(i) dans une boucle.

clearFormArray = (formArray: FormArray) => {
  while (formArray.length !== 0) {
    formArray.removeAt(0)
  }
}

L'avantage de cette approche est que toutes les souscriptions sur votre formArray, telle que celle enregistrée avec formArray.valueChanges, ne seront pas perdues.

Consultez le documentation FormArray pour plus d'informations.


Méthode plus propre (mais casse les références d'abonnement)

Vous pouvez remplacer tout FormArray par un nouveau.

clearFormArray = (formArray: FormArray) => {
  formArray = this.formBuilder.array([]);
}

Cette approche pose un problème si vous êtes abonné à l'observable formArray.valueChanges! Si vous remplacez le tableau FromArray par un nouveau tableau, vous perdrez la référence à l'observable auquel vous êtes abonné.

97
CamelD

Ou vous pouvez simplement effacer les contrôles

this.myForm= {
     name: new FormControl(""),
     desc: new FormControl(""),
     arr: new FormArray([])
}

Ajouter quelque chose array

const arr = <FormArray>this.myForm.controls.arr;
arr.Push(new FormControl("X"));

Effacer le tableau

const arr = <FormArray>this.myForm.controls.arr;
arr.controls = [];

Lorsque vous avez plusieurs choix sélectionnés et clairs, parfois, la vue n'est pas mise à jour. Une solution consiste à ajouter

arr.removeAt(0)

MISE À JOUR

Une solution plus élégante pour utiliser des tableaux de formulaires consiste à utiliser un getter en haut de votre classe pour pouvoir y accéder.

get inFormArray(): FormArray {
    this.myForm.get('inFormArray') as FormArray;
}

Et de l'utiliser dans un template

<div *ngFor="let c of inFormArray; let i = index;" [formGroup]="i">
other tags...
</div>

Réinitialiser:

inFormArray.reset();

Pousser:

inFormArray.Push(new FormGroup({}));

Supprimer la valeur à l'index: 1

inFormArray.removeAt(1);
22
Pian0_M4n

Angular v4.4 si vous avez besoin de sauvegarder la même référence à l’instance de FormArray, essayez ceci:

purgeForm(form: FormArray) {
  while (0 !== form.length) {
    form.removeAt(0);
  }
}
7
Alex Dzeiko

À partir de Angular 8+, vous pouvez utiliser clear() pour supprimer tous les contrôles du FormArray:

const arr = new FormArray([
   new FormControl(),
   new FormControl()
]);
console.log(arr.length);  // 2

arr.clear();
console.log(arr.length);  // 0

Pour les versions précédentes, la méthode recommandée est la suivante:

while (arr.length) {
   arr.removeAt(0);
}

https://angular.io/api/forms/FormArray#clear

6
crappylime

Attention!

La Angular v6.1.7 documentation FormArray dit:

Pour modifier les contrôles du tableau, utilisez les méthodes Push, insert ou removeAt dans FormArray même. Ces méthodes garantissent que les contrôles sont correctement suivis dans la hiérarchie du formulaire. Ne modifiez pas le tableau de AbstractControls utilisé pour instancier directement le FormArray, car cela entraînerait un comportement étrange et inattendu tel que la détection de modification interrompue.

Gardez cela à l’esprit si vous utilisez la fonction splice directement sur le tableau controls comme l’une des réponses suggérées.

Utilisez la fonction removeAt.

  while (formArray.length !== 0) {
    formArray.removeAt(0)
  }
5
zgue

Si la structure de données de ce que vous allez remplacer par les informations du tableau correspond à ce qui existe déjà, vous pouvez utiliser patchValue

https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html#!#reset-anchor

patchValue (valeur: any [], {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Corrige la valeur du FormArray. 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.

Il accepte les super-ensembles et les sous-ensembles du tableau sans générer d'erreur.

const arr = new FormArray([
   new FormControl(),
   new FormControl()
]);
console.log(arr.value);   // [null, null]
arr.patchValue(['Nancy']);
console.log(arr.value);   // ['Nancy', null]

Sinon, vous pouvez utiliser reset

reset (valeur ?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Réinitialise le FormArray. Cela signifie par défaut:

Le tableau et tous ses descendants sont marqués comme neufs. Le tableau et tous les descendants sont marqués comme non modifiés. La valeur de tous les descendants sera null ou null. Vous pouvez également rétablir un état de formulaire spécifique en transmettant un tableau d'états correspondant à la structure du contrôle. . L'état peut être une valeur autonome ou un objet d'état de formulaire avec une valeur et un statut désactivé.

this.arr.reset(['name', 'last name']);
console.log(this.arr.value);  // ['name', 'last name']

OR

this.arr.reset([   {value: 'name', disabled: true},   'last' ]);
console.log(this.arr.value);  // ['name', 'last name']
console.log(this.arr.get(0).status);  // 'DISABLED'

Voici une démo forkée de certains travaux antérieurs de la mienne démontrant une utilisation très simple de chacun.

3
silentsod

Mise à jour: Angular 8 dispose enfin d'une méthode pour effacer le tableau Array FormArray.clear ()

2
nightingale2k1

La boucle While prendra beaucoup de temps pour supprimer tous les éléments si le tableau en contient 100. Vous pouvez vider les propriétés de contrôle et de valeur de FormArray comme ci-dessous.

clearFormArray = (formArray: FormArray) => {formArray.controls = []; formArray.setValue ([]); }

0
user3067875

Pour garder le code propre, j'ai créé la méthode d'extension suivante pour toute personne utilisant Angular 7 et versions ultérieures. Cela peut également être utilisé pour étendre toute autre fonctionnalité des formes réactives.

import { FormArray } from '@angular/forms';

declare module '@angular/forms/src/model' {
  interface FormArray {
    clearArray: () => FormArray;
  }
}

FormArray.prototype.clearArray = function () {
  const _self = this as FormArray;
  _self.controls = [];
  _self.setValue([]);
  _self.updateValueAndValidity();
  return _self;
}

0
Danielok1993

angulaire 8

utilisez simplement la méthode clear() sur formArrays:

(this.invoiceForm.controls['other_Partners']).clear();
0
MajiD

dans la dernière version, vous pouvez utiliser FormArray.reset ()

0
dam