Angular 2: Reaktif form kontrollerini yineleyin


Yanıtlar:


199

Bunu Object.keyshalledebileceğini öğrendim ..

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

Angular 8+ için aşağıdakileri kullanın (Michelangelo cevabına göre):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

2
Bu işlevi onSubmit'te kullandığımda hata alıyorum Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.Nedenini bilen var mı?
maidi

1
Object.keys (this.registerForm.controls) .forEach (anahtar => {this.registerForm.controls [anahtar] .markAsDirty ();});
Foad

Object.keys veya "for in" i denediğimde hiçbir şey alamıyorum. Yine de, console.log (form.controls), nesnenin içerdiği tüm çeşitli form denetimlerini GÖRÜYORUM. Şaşkınım.
Jake Shakesworth

Angular 5 kullanıldığında, markAsDirty () / markAsTouched () herhangi bir alt FormGrubu içinde yinelenmez. Yukarıdaki kodu özyinelemeli bir işleve dönüştürdüm ve herhangi bir alt FormGroup'ta çağırdım. Bir kullanıcının gerekli bir öğeye hiç dokunmaması durumunda mevcut Angular Material UI projesi ile daha iyi çalışır, kullanıcı o noktada herhangi birini işaretlemek için formu göndermeye çalıştığında onu çağırırım.
Robert

3
Yazımı okuduğunuz ve kendi cevabınızı güncellediğiniz için teşekkürler. Resmi belgeler de güncelliğini yitirdi, bu yüzden her satırı yazdırarak bunu anlamalıydım ...
Michelangelo

56

Değeri ne olursa olsun, bunu Object.keys (...) sihrini kullanmak zorunda kalmadan yapmanın başka bir yolu var :

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

Döngünün indeksi nasıl alınır?
SVK

1
TSLint kullananlar için kod çalışır, ancak TSLint "for (... in ...) ifadeleri bir if ifadesiyle filtrelenmelidir (forin)" ile şikayet eder.
Yennefer

1
tslint, for ... in ifadesinin JavaScript belgelerinden bir alıntıya işaret ediyor stackoverflow.com/questions/40770425/…
Egle Kreivyte

41

Kabul edilen yanıt, düz bir form yapısı için doğrudur, ancak orijinal soruyu tam olarak yanıtlamaz. Bir web sayfası iç içe geçmiş FormGroups ve FormArrays gerektirebilir ve sağlam bir çözüm oluşturmak için bunu hesaba katmalıyız.

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

olacak instanceofhep typescript tarafından transpiled sonra işe?
önemli

@ the-notable instanceof, TypeScript'e özgü bir anahtar kelime değildir ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) classVeri türü de değildir.
Keenan Diggs

8

@Marcos yanıtını kullanarak, bir formGroup'u parametre olarak iletmek olarak adlandırılabilecek bir işlev oluşturdum ve her formGroup alt kontrolünü kirli olarak işaretler, örneğin onu bir hizmetin içine koyarak kodun etrafındaki daha fazla yerden kullanılabilir hale getirmek için.

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

Umarım yardımcı olur ;)


Mükemmel! ClearValidators, untouch, vb. İçin benzer işlevlerle birlikte hizmete eklendi. Yuvalanmış denetimler için yinelemeli denetim eklemek isteyebilirsiniz, ancak bu şimdilik çalışıyor. Teşekkürler!
mc01

6

Görünüşe göre bu get işlev, Angular 8'deki formunuzdaki belirli değerleri almak için artık çalışmıyor, bu yüzden @Liviu Ilea'nın cevabına dayanarak onu bu şekilde çözdüm.

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

Emin misiniz? API doc, Soyut Denetim için zaten bir get yöntemine sahiptir ( angular.io/api/forms/AbstractControl#get ). Henüz göç etmedim. Şimdi korkuyorum (⊙_ ◎)
Alan Grosz

@AlanGrosz Evet, bunu yeniden yazarken de gördüm, ancak konsoldaki tüm satırları yazdırırken bile nesne üzerinde herhangi bir alma yöntemi bulamadım. Sanırım dokümantasyon geride kaldı. Göç ederken iyi şanslar!
Michelangelo

Kaldırdıklarını sanmıyorum, benim için Angular 8'de çalışsın. Ayrıca hala dokümantasyonda. angular.io/api/forms/AbstractControl#get
Laszlo Sarvold

5

    Object.keys( this.registerForm.controls).forEach(key => {
       this.registerForm.controls[key].markAsDirty();
    });


4

Bu benim için çalışan şey

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

1

Bunu yapmak için bu işlevi yaratıyorum * 'order' adında bir kontrole sahibim ve indeksi ona iletiyorum.

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
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.