Angular'daki FormArray'deki tüm öğeleri kaldırma


87

FormBuilder içinde bir form dizim var ve formları dinamik olarak değiştiriyorum, yani uygulama 1'den tıklama yükleme verileri vb.

Karşılaştığım sorun, tüm verilerin yüklendiği, ancak FormArray'deki verilerin kalması ve eski öğeleri yenileriyle birleştirmesidir.

FormArray'in yalnızca yeni öğelere sahip olmasını nasıl temizlerim.

Bunu denedim

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

ama işe yaramıyor.

Herhangi bir fikir?

ngOnInit(): void {
  this.route.params.subscribe(params => {
    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 });
      }
    });
}

ngOnInit tıklamayla çağrılmıyor


İlgili bir sorun burada Angular
deposunda

Yanıtlar:


148

Aynı problemim vardı. Bu sorunu çözmenin iki yolu vardır.

Aboneliği koru

removeAt(i)İşlevi bir döngüde çağırarak her FormArray öğesini manuel olarak temizleyebilirsiniz .

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

Bu yaklaşımın avantajı formArray, kayıtlı olanlar gibi sizin üzerindeki hiçbir aboneliğinizin formArray.valueChangeskaybolmayacağıdır.

Daha fazla bilgi için FormArray belgelerine bakın .


Daha temiz yöntem (ancak abonelik referanslarını bozar)

FormArray'in tamamını yenisiyle değiştirebilirsiniz.

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

Bu yaklaşım, formArray.valueChangesgözlemlenebilir olana abone olmanız durumunda bir soruna neden olur ! FromArray'i yeni bir diziyle değiştirirseniz, abone olduğunuz gözlemlenebilir olanın referansını kaybedersiniz.


73
Angular 8+ itibariyle, bir FormArray'den tüm bileşenleri kaldırmanın tercih edilen yolu kullanmaktırformArray.clear();
Renan

2
Ayrıca, yourFormArray.setValue ([])); ve yourFormGroup.setControl ('yourFormArray', []);
Oscar

1
Bu yaklaşımla güle güle doğrulama
Andre Elrico

@Renan formControl kullanıyorum
Emir Herrera

31

Veya sadece kontrolleri temizleyebilirsiniz

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

Bir şeyler ekle array

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

Diziyi temizle

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

Birden çok seçeneği seçip temizlediğinizde, bazen görünümü güncellemez. Bir geçici çözüm eklemek

arr.removeAt(0)

GÜNCELLEME

Form dizilerini kullanmak için daha zarif bir çözüm, sınıfınızın en üstünde bir alıcı kullanmaktır ve sonra ona erişebilirsiniz.

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

Ve bir şablonda kullanmak için

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

Sıfırla:

inFormArray.reset();

İt:

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

Dizindeki değeri kaldır: 1

inFormArray.removeAt(1);

GÜNCELLEME 2:

Kısmi nesne alın, tüm hataları JSON ve diğer birçok özellik olarak alın, NaoFormsModule kullanın


6
"Arr.controls = [];" söz gerçekten harika!
dotNetkow

@Pian, Yalnızca const arr = <FormArray> this.myForm.controls.arr; arr.controls = []; form dizisini temizlemek için çalışıyor. TQ
chandoo

inFormArray.at(1).remove(); bana bir [ts] Property 'remove' does not exist on type 'AbstractControl'.aktarıcı hatası veriyor .
zgue

Şablonunuzda @ Pian0_M4n let c of inFormArrayolmalı let c of inFormArray.controls?
wal

23

Angular 8+ itibariyle clear()FormArray'deki tüm denetimleri kaldırmak için kullanabilirsiniz:

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

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

Önceki sürümler için önerilen yol şudur:

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

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


1
Burada Angular 8+ 'den bahsettiğiniz için teşekkür ederiz.
Patrick Hillert

11

Açısal 8

clear()formArrays üzerinde basitçe yöntemi kullanın :

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

8

Angular v4.4, FormArray örneğine aynı başvuruyu kaydetmeniz gerekirse şunu deneyin:

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

Öğeleri diziden çıkarırken aboneliği korumanın iyi bir yolu.
red_dorian

@mtpultz, lütfen kabul edilen cevabın değişim günlüğünü ( stackoverflow.com/posts/41856927/revisions ) not edin . Zamanla bu cevabı bıraktığımda kabul edilen cevap mevcut olandan farklıydı.
Alex Dzeiko

8

Uyarı!

Angular v6.1.7 FormArray belgeleri şunları söylüyor:

Dizideki denetimleri değiştirmek için FormArray'in kendisinde push, insert veya removeAt yöntemlerini kullanın. Bu yöntemler, kontrollerin formun hiyerarşisinde düzgün bir şekilde izlenmesini sağlar. Doğrudan FormArray'i başlatmak için kullanılan AbstractControls dizisini değiştirmeyin, aksi takdirde bozuk değişiklik algılama gibi garip ve beklenmedik davranışlara neden olur.

spliceİşlevi doğrudan controlsdizi üzerinde önerilen yanıtlardan biri olarak kullanıyorsanız bunu aklınızda bulundurun .

removeAtİşlevi kullanın .

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

6

Diziniz için kolayca bir alıcı tanımlayabilir ve aşağıdaki gibi temizleyebilirsiniz:

  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()
  }

5

Güncelleme: Angular 8 sonunda FormArray.clear () dizisini temizlemek için bir yöntem aldı


5

FormArray'deki bir dizinin tüm öğelerini kaldırmak için FormArray.clear () kullanın


4

Angular 8'den beri this.formArray.clear()form dizisindeki tüm değerleri temizlemek için kullanabilirsiniz . Tüm öğeleri tek tek kaldırmaktan daha basit ve daha verimli bir alternatif


3

Dizideki bilgileri halihazırda kullanabileceğiniz eşleşmelerle değiştireceğiniz şey için veri yapısı sağlanır. patchValue

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

patchValue (değer: herhangi [], {onlySelf, emitEvent} ?: {onlySelf ?: boolean, emitEvent ?: boolean}): void FormArray değerini yamalar. Kontrolün yapısıyla eşleşen bir diziyi kabul eder ve değerleri gruptaki doğru kontrollerle eşleştirmek için elinden gelenin en iyisini yapar.

Bir hata atmadan dizinin hem süper kümelerini hem de alt kümelerini kabul eder.

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

Alternatif olarak kullanabilirsiniz reset

reset (value ?: any, {onlySelf, emitEvent} ?: {onlySelf ?: boolean, emitEvent ?: boolean}): void FormArray'i sıfırlar. Bu, varsayılan olarak şu anlama gelir:

Dizi ve tüm alt öğeleri bozulmamış olarak işaretlenmiştir Dizi ve tüm alt öğeleri dokunulmamış olarak işaretlenmiştir Tüm alt bileşenlerin değeri boş veya boş eşlemler olacaktır Ayrıca, denetimin yapısıyla eşleşen bir durum dizisi içinde geçerek belirli bir form durumuna sıfırlayabilirsiniz. . Durum, bağımsız bir değer veya hem değeri hem de devre dışı durumu olan bir form durumu nesnesi olabilir.

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

VEYA

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

İşte , her birinin çok basit bir kullanımını gösteren, daha önceki bazı maden çalışmalarından çatallı bir Plunker demosu.


elbette bu, dizide tam olarak aynı sayıda öğeye sahip olmanız gerektiği anlamına gelir.
Simon_Weaver

2

FormArray kullanmayı hiç denemedim, her zaman FormGroup ile çalıştım ve tüm kontrolleri aşağıdakileri kullanarak kaldırabilirsiniz:

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

formGroup olmak, FormGroup örneğidir.


1

Kodu temiz tutmak için Angular 7 ve altını kullanan herkes için aşağıdaki uzantı yöntemini oluşturdum. Bu aynı zamanda Reaktif Formların diğer herhangi bir işlevselliğini genişletmek için de kullanılabilir.

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


1

Çok geç kaldım ama döngülere ihtiyaç duymadığınız başka bir yol buldum. dizi denetimini boş olarak ayarlayarak diziyi sıfırlayabilirsiniz.

Aşağıdaki kod dizinizi sıfırlayacaktır.

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


0

Dizide 100 öğe varsa döngü tüm öğeleri silmek uzun zaman alacaktır. FormArray'in hem kontrollerini hem de değer özelliklerini aşağıdaki gibi boşaltabilirsiniz.

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


0

Angular 7 veya önceki bir sürümü kullanıyorsanız ve clear () yöntemine erişiminiz yoksa, herhangi bir döngü yapmadan bunu başarmanın bir yolu vardır:

yourFormGroup.controls.youFormArrayName = new FormArray([]);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.