Sudut 2: Iterasi di atas kontrol bentuk reaktif

97

Saya ingin markAsDirtysemua kontrol di dalam a FormGroup.

Marcos JC Kichel
sumber

Jawaban:

199

Ketemu yang Object.keysbisa menangani ini ..

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

Untuk Angular 8+, gunakan yang berikut (berdasarkan jawaban Michelangelo):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });
Marcos JC Kichel
sumber
2
Ketika saya menggunakan fungsi ini di onSubmit, saya mendapatkan error Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.Apakah ada yang tahu mengapa?
maidi
1
Object.keys (this.registerForm.controls) .forEach (key => {this.registerForm.controls [key] .markAsDirty ();});
Muat
Ketika saya mencoba Object.keys atau bahkan "untuk masuk", saya tidak mendapatkan apa-apa. Namun, jika saya console.log (form.controls) saya bisa MELIHAT semua berbagai kontrol formulir yang terdapat dengan objek. Saya bingung.
Jake Shakesworth
Menggunakan Angular 5, markAsDirty () / markAsTouched () tidak muncul kembali ke sub-FormGroups. Saya memecahkan kode di atas menjadi fungsi rekursif dan memanggilnya di sub-FormGroups apa pun. Berfungsi lebih baik dengan proyek UI Angular Material saat ini jika pengguna tidak pernah menyentuh elemen yang diperlukan, saya menyebutnya saat pengguna mencoba mengirimkan formulir untuk menandai salah satu pada saat itu.
Robert
3
Terima kasih telah membaca posting saya dan memperbarui jawaban Anda sendiri. Dokumen resmi juga sudah ketinggalan zaman, jadi saya harus mencari tahu dengan mencetak setiap baris ...
Michelangelo
56

Untuk apa nilainya, ada cara lain untuk melakukan ini tanpa harus menggunakan sihir Object.keys (...) :

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

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

}
Liviu Ilea
sumber
bagaimana cara mendapatkan indeks loop?
SVK
1
Untuk mereka yang menggunakan TSLint, kodenya berfungsi, tetapi TSLint mengeluh dengan "untuk (... di ...) pernyataan harus disaring dengan pernyataan if (forin)".
Yennefer
1
tslint menunjukkan, kutipan dari dokumentasi JavaScript untuk ... dalam pernyataan stackoverflow.com/questions/40770425/…
Egle Kreivyte
41

Jawaban yang diterima benar untuk struktur bentuk datar, tetapi tidak sepenuhnya menjawab pertanyaan awal. Halaman web mungkin memerlukan FormGroups dan FormArays bersarang, dan kita harus memperhitungkannya untuk membuat solusi yang kuat.

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();
        }
    });
}
Keenan Diggs
sumber
akan instanceofselalu berfungsi setelah ditranspilasi oleh Typecript?
yang terkenal
@ the-notable instanceofbukanlah kata kunci khusus TypeScript ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) Begitu juga dengan classtipe datanya.
Keenan Diggs
8

Dengan menggunakan jawaban @Marcos, saya membuat sebuah fungsi yang dapat disebut meneruskan formGroup sebagai parameter dan menandai setiap kontrol anak formGroup menjadi kotor, hanya untuk membuatnya dapat digunakan dari lebih banyak tempat di sekitar kode yang meletakkannya di dalam layanan, misalnya.

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

semoga membantu;)

Hugo
sumber
Sempurna! Ditambahkan ke layanan, bersama dengan fungsi yang mirip dengan clearValidators, untouch, dll. Mungkin ingin menambahkan pemeriksaan rekursif untuk kontrol bersarang, tetapi ini berfungsi untuk saat ini. Terima kasih!
mc01
6

Tampaknya get fungsi itu tidak berfungsi lagi untuk mengambil nilai tertentu dalam formulir Anda di Angular 8, jadi inilah cara saya menyelesaikannya berdasarkan jawaban dari @Liviu Ilea.

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}
Michelangelo
sumber
Apakah kamu yakin Dokumen API memiliki metode get untuk Kontrol Abstrak ( angular.io/api/forms/AbstractControl#get ). Saya belum bermigrasi. Sekarang saya takut (⊙_ ◎)
Alan Grosz
@AlanGrosz Ya, saya melihat itu juga ketika saya menulis ulang tetapi bahkan ketika mencetak semua baris di konsol saya tidak dapat menemukan metode get pada objek. Saya pikir dokumentasinya ada di belakang. Semoga berhasil bermigrasi!
Michelangelo
Saya tidak berpikir mereka menghapusnya, dapatkan pekerjaan untuk saya di Angular 8. Juga masih ada di dokumentasi angular.io/api/forms/AbstractControl#get
Laszlo Sarvold
5

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

Foad
sumber
4

Inilah yang berhasil untuk saya

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

Saya membuat fungsi ini untuk membuatnya * Saya memiliki kontrol dengan nama 'order', dan memberikan indeks kepadanya.

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


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
João Marcos Santos Teixeira
sumber