Winkel 2 Entfernen Sie alle Elemente aus einem Formarray

86

Ich habe ein Formulararray in einem Formbuilder und ändere Formulare dynamisch, dh beim Klicken Daten aus Anwendung 1 laden usw.

Das Problem, das ich habe, ist, dass alle Daten geladen werden, aber die Daten im Formulararray bleiben und nur die alten Elemente mit neuen verknüpfen.

Wie lösche ich dieses Formular, um nur die neuen Elemente zu haben?

Ich habe es versucht

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

aber es funktioniert nicht.

Irgendwelche Ideen? Vielen Dank

in 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 wird beim Klicken nicht aufgerufen

Karl O'Connor
quelle
Ein verwandtes Problem wird hier auf dem Angular Repo
E. Sundin

Antworten:

145

Ich hatte das gleiche Problem. Es gibt zwei Möglichkeiten, um dieses Problem zu lösen.

Abonnement beibehalten

Sie können jedes FormArray-Element manuell löschen, indem Sie die removeAt(i)Funktion in einer Schleife aufrufen .

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

Der Vorteil dieses Ansatzes besteht darin, dass Abonnements auf Ihrem Konto formArray, wie das bei registrierte formArray.valueChanges, nicht verloren gehen.

Weitere Informationen finden Sie in der FormArray-Dokumentation .


Sauberere Methode (bricht jedoch Abonnementreferenzen)

Sie können das gesamte FormArray durch ein neues ersetzen.

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

Dieser Ansatz verursacht ein Problem, wenn Sie das formArray.valueChangesObservable abonniert haben ! Wenn Sie das FromArray durch ein neues Array ersetzen, verlieren Sie den Verweis auf das Observable, das Sie abonniert haben.

CamelD
quelle
67
Ab Angular 8+ ist die bevorzugte Methode zum Entfernen aller Komponenten aus einem FormArray die Verwendung vonformArray.clear();
Renan
2
Auch yourFormArray.setValue ([])); und yourFormGroup.setControl ('yourFormArray', []);
Oscar
1
Tschüss Validierung mit diesem Ansatz
Andre Elrico
@ Renan Ich benutze formControl
Emir Herrera
29

Oder Sie können einfach die Steuerelemente löschen

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

Füge etwas hinzu array

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

Löschen Sie das Array

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

Wenn Sie mehrere Auswahlmöglichkeiten ausgewählt und gelöscht haben, wird die Ansicht manchmal nicht aktualisiert. Eine Problemumgehung ist das Hinzufügen

arr.removeAt(0)

AKTUALISIEREN

Eine elegantere Lösung für die Verwendung von Formulararrays ist die Verwendung eines Getters an der Spitze Ihrer Klasse, auf den Sie zugreifen können.

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

Und um es in einer Vorlage zu verwenden

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

Zurücksetzen:

inFormArray.reset();

Drücken:

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

Wert am Index entfernen: 1

inFormArray.removeAt(1);

UPDATE 2:

Teilobjekt abrufen , alle Fehler als JSON abrufen und viele andere Funktionen verwenden, das NaoFormsModule verwenden

Pian0_M4n
quelle
5
Die "arr.controls = [];" Erwähnung ist wirklich toll!
dotNetkow
@Pian, Only const arr = <FormArray> this.myForm.controls.arr; arr.controls = []; arbeitet daran, das Formulararray zu löschen. TQ
Chandoo
inFormArray.at(1).remove(); gibt mir einen [ts] Property 'remove' does not exist on type 'AbstractControl'.Transpilerfehler.
Zgue
@ Pian0_M4n in Ihrer Vorlage let c of inFormArraysollte sein let c of inFormArray.controls?
Wal
22

Ab Angular 8+ können Sie clear()alle Steuerelemente im FormArray entfernen:

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

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

Für frühere Versionen wird empfohlen:

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

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

Crappylime
quelle
1
Vielen Dank, dass Sie Angular 8+ hier erwähnt haben.
Patrick Hillert
10

Winkel 8

Verwenden Sie einfach die clear()Methode für formArrays:

(this.invoiceForm.controls['other_Partners'] as FormArray).clear();
MajiD
quelle
8

Angular v4.4 Wenn Sie denselben Verweis auf die Instanz von FormArray speichern müssen, versuchen Sie Folgendes:

purgeForm(form: FormArray) {
  while (0 !== form.length) {
    form.removeAt(0);
  }
}
Alex Dzeiko
quelle
Gute Möglichkeit, das Abonnement beizubehalten, während Elemente aus dem Array entfernt werden.
red_dorian
@mtpultz Bitte beachten Sie das Änderungsprotokoll ( stackoverflow.com/posts/41856927/revisions ) der akzeptierten Antwort. Zu der Zeit, als ich diese Antwort verließ, war die akzeptierte Antwort anders als die aktuelle.
Alex Dzeiko
8

Warnung!

In der AngAr v6.1.7 FormArray-Dokumentation heißt es:

Verwenden Sie zum Ändern der Steuerelemente im Array die Push-, Insert- oder RemoveAt-Methoden in FormArray. Diese Methoden stellen sicher, dass die Steuerelemente in der Hierarchie des Formulars ordnungsgemäß verfolgt werden. Ändern Sie nicht das Array von AbstractControls, mit dem das FormArray direkt instanziiert wird, da dies zu seltsamem und unerwartetem Verhalten wie der Erkennung fehlerhafter Änderungen führt.

Denken Sie daran, wenn Sie die spliceFunktion direkt auf dem controlsArray als eine der vorgeschlagenen Antworten verwenden.

Verwenden Sie die removeAtFunktion.

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

Sie können einen Getter für Ihr Array einfach definieren und wie folgt löschen:

  formGroup: FormGroup    
  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this.fb.group({
      sliders: this.fb.array([])
    })
  }
  get sliderForms() {
    return this.formGroup.get('sliders') as FormArray
  }

  clearAll() {
    this.formGroup.reset()
    this.sliderForms.clear()
  }
M.Reza
quelle
Thx Es funktioniert ......
nos nart
5

Update: Angular 8 hat endlich die Methode zum Löschen des Arrays FormArray.clear () erhalten

Nachtigall2k1
quelle
4

Seit Angular 8 können Sie this.formArray.clear()alle Werte im Formulararray löschen. Dies ist eine einfachere und effizientere Alternative zum Entfernen aller Elemente nacheinander

Nikita Korba
quelle
4

Verwenden Sie FormArray.clear (), um alle Elemente eines Arrays in einem FormArray zu entfernen

Anu Priya
quelle
3

Die Datenstruktur für das, was Sie ersetzen möchten, wird durch Übereinstimmungen mit den bereits vorhandenen Daten bereitgestellt patchValue

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

patchValue (Wert: any [], {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Patchet den Wert des FormArray. Es akzeptiert ein Array, das der Struktur des Steuerelements entspricht, und bemüht sich, die Werte den richtigen Steuerelementen in der Gruppe zuzuordnen.

Es akzeptiert sowohl Super- als auch Teilmengen des Arrays, ohne einen Fehler auszulösen.

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

Alternativ könnten Sie verwenden reset

reset (Wert?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Setzt das FormArray zurück. Dies bedeutet standardmäßig:

Das Array und alle Nachkommen sind als makellos markiert. Das Array und alle Nachkommen sind als unberührt markiert. Der Wert aller Nachkommen ist null oder null. Sie können auch auf einen bestimmten Formularstatus zurücksetzen, indem Sie ein Array von Status übergeben, das der Struktur des Steuerelements entspricht . Der Status kann ein eigenständiger Wert oder ein Formularstatusobjekt mit einem Wert und einem deaktivierten Status sein.

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

ODER

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

Hier ist eine gegabelte Plunker-Demo aus einer früheren Arbeit von mir, die eine sehr einfache Verwendung von jedem zeigt.

silentsod
quelle
Dies bedeutet sicherlich, dass Sie genau die gleiche Anzahl von Elementen im Array haben müssen.
Simon_Weaver
2

Ich habe nie versucht, formArray zu verwenden, ich habe immer mit FormGroup gearbeitet, und Sie können alle Steuerelemente entfernen mit:

Object.keys(this.formGroup.controls).forEach(key => {
          this.formGroup.removeControl(key);
        });

FormGroup ist eine Instanz von FormGroup.

Pianisimo
quelle
1

Ich bin sehr spät dran, aber ich habe einen anderen Weg gefunden, auf dem Sie keine Schleifen benötigen. Sie können das Array zurücksetzen, indem Sie das Array-Steuerelement auf leer setzen.

Der folgende Code setzt Ihr Array zurück.

this.form.setControl('name', this.fb.array([]))

Als ob
quelle
0

Die while-Schleife benötigt lange, um alle Elemente zu löschen, wenn das Array 100 Elemente enthält. Sie können die Steuerelemente und Werteigenschaften von FormArray wie unten beschrieben leeren.

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

user3067875
quelle
0

Um den Code sauber zu halten, habe ich die folgende Erweiterungsmethode für alle Benutzer von Angular 7 und darunter erstellt. Dies kann auch verwendet werden, um andere Funktionen von Reactive Forms zu erweitern.

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;
}

Danielok1993
quelle