angular 2 Retirer tous les articles d'un formarray

j'ai un tableau de formulaires à l'intérieur d'un formbuilder et je change dynamiquement les formulaires, i.e. sur les données de charge de clic de l'application 1 etc.

le problème que j'ai est que tous les chargements de données dans mais les données dans le formarray reste et concasse juste les anciens articles avec nouveau.

Comment puis-je obtenir que formarray avoir seulement les nouveaux articles.

j'ai essayé

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

mais ça ne fonctionne pas.

des idées? merci

dans 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é sur click

30
demandé sur Karl O'Connor 2017-01-25 15:55:39

6 réponses

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

Conserver votre abonnement

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

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

l'avantage de cette approche est que tout Abonnement sur votre formArray, tel que celui enregistré avec formArray.valueChanges ne sera pas perdue.

voir le FormArray documentation pour en savoir plus information.


méthode plus propre (mais brise abonnement références)

vous pouvez remplacer tout Formarra par un nouveau.

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

cette approche cause un problème si vous êtes abonné au formArray.valueChanges observable! Si vous remplacez le FromArray avec un nouveau tableau, vous perdrez la référence à l'observable que vous êtes abonné.

53
répondu CamelD 2017-12-23 21:46:47

Ou vous pouvez simplement effacer les commandes

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 il ne met pas à jour la vue. Une solution de contournement consiste à ajouter

arr.removeAt(0)

UPDATE

une solution plus élégante pour utiliser des tableaux de formes est d'utiliser un getter au sommet de votre classe et alors vous pouvez 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>

Reset:

inFormArray.reset();

Commande:

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

supprimer la valeur à l'index: 1

inFormArray.removeAt(1);
17
répondu Pian0_M4n 2018-09-16 09:25:20

semble que la façon la plus facile de faire ceci est d'utiliser épissure sans supprimer le paramètre de sorte qu'il supprime tous les éléments, puis c'est tout en une seule ligne de code:

yourFormArray.controls.splice(0);

la référence au tableau de formulaires n'est pas perdue donc vos Abonnements vont persister, et il n'a pas besoin d'une boucle.

8
répondu mtpultz 2018-07-11 05:46:59

angle 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);
  }
}
6
répondu Alex Dzeiko 2017-11-29 12:21:20

fourni la structure de données pour ce que vous allez remplacer l'information dans le tableau par correspondances ce qui est déjà là, vous pouvez utiliser patchValue

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

patchValue(valeur: [], {onlySelf, emitEvent}?: {onlySelf?: booléen, emitEvent?: boolean}): vide Patches la valeur du FormArray. Il accepte un tableau qui correspond à la structure de la de contrôle, et faire de son mieux pour faire correspondre les valeurs à la bonne contrôles dans le groupe.

il accepte à la fois les super-ensembles et les sous-ensembles du tableau sans lancer erreur.

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

vous pouvez aussi utiliser reset

réinitialiser(valeur?: any, {onlySelf, emitEvent}?: {onlySelf?: booléen, emitEvent?: boolean}): void reset the FormArray. Cela signifie par valeur par défaut:

Le tableau et tous les descendants sont le tableau et tout le reste sont intacts. les descendants sont marqués intacte La valeur de tous les descendants seront les cartes null ou null vous pouvez également réinitialiser à un État de forme spécifique par passant dans un tableau d'États qui correspond à la structure du contrôle. L'état peut être une valeur autonome ou un objet d'état de forme avec à la fois une valeur et un état 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'

Ici fourchue Plunker démo de certains travaux antérieurs de la mine demoing une utilisation très simple de chacun.

3
répondu silentsod 2017-01-25 22:44:52

Attention!

le V6 angulaire.1.7 FormArray documentation dit:

pour changer les commandes dans le tableau, utilisez le push, insert, ou removeAt méthodes dans FormArray lui-même. Ces méthodes garantissent que les contrôles sont correctement suivi dans la hiérarchie de la forme. Ne pas modifier le tableau de AbstractControls utilisé pour instancier le FormArray directement, comme cela résulte en un comportement étrange et inattendu tel que le changement cassé détection.

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

removeAt fonction.

  while (formArray.length !== 0) {
    formArray.removeAt(0)
  }
1
répondu zgue 2018-09-14 10:30:24