Bagaimana menemukan kontrol yang tidak valid dalam bentuk reaktif sudut 4

92

Saya memiliki bentuk reaktif di Angular seperti di bawah ini:

this.AddCustomerForm = this.formBuilder.group({
    Firstname: ['', Validators.required],
    Lastname: ['', Validators.required],
    Email: ['', Validators.required, Validators.pattern(this.EMAIL_REGEX)],
    Picture: [''],
    Username: ['', Validators.required],
    Password: ['', Validators.required],
    Address: ['', Validators.required],
    Postcode: ['', Validators.required],
    City: ['', Validators.required],
    Country: ['', Validators.required]
});

createCustomer(currentCustomer: Customer) 
{
    if (!this.AddCustomerForm.valid)
    {
        //some app logic
    }
}

this.AddCustomerForm.valid mengembalikan false, tetapi semuanya terlihat bagus.

Saya telah mencoba untuk menemukan dengan memeriksa properti status di koleksi kontrol. Tetapi saya bertanya-tanya apakah ada cara untuk menemukan yang tidak valid dan menampilkannya kepada pengguna?

sa_
sumber
Jika Anda hanya ingin menampilkan bidang dengan kesalahan, Anda dapat menggunakan css untuk menyorot atau mewarnai bidang yang tidak valid. Setiap bidang yang tidak valid memiliki kelas "ng-invalid" yang ditambahkan dalam daftar kelasnya
LookForAngular

Jawaban:

176

Anda cukup mengulang setiap kontrol dan memeriksa status:

    public findInvalidControls() {
        const invalid = [];
        const controls = this.AddCustomerForm.controls;
        for (const name in controls) {
            if (controls[name].invalid) {
                invalid.push(name);
            }
        }
        return invalid;
    }
Max Koretskyi
sumber
1
terima kasih untuk ini tetapi saya mencoba ini dan bahkan ini tidak mengembalikan apa pun bentuk saya masih tidak valid, ini aneh. Maksud saya, kode ini terlihat bagus tetapi tidak masuk akal mengapa form.valid mengembalikan false
sa_
apa yang findInvalidControls()mengembalikanmu?
Max Koretskyi
1
itu tidak mengembalikan apa-apa, tidak valid kosong. Saya memeriksa satu per satu di layar arloji debug, semua kontrol valid tetapi this.AddCustomerForm.valid masih mengembalikan false.
SA_
Saya pikir saya menemukan. ada bidang email dan ekspresi reguler tetapi entah bagaimana status kontrolnya TERTUNDA dan mungkin penyebabnya
sa_
7
@ AngularInDepth.com - jika salah satu kontrol adalah grup formulir, fungsi Anda akan mengembalikan grup formulir tidak valid dan bukan kontrol formulir tertentu yang tidak valid
john Smith
36

Saya baru saja mengatasi masalah ini: Setiap bidang formulir valid, tetapi formulir itu sendiri tidak valid.

Ternyata saya telah menetapkan 'Validator.required' pada FormArray di mana kontrol ditambahkan / dihapus secara dinamis. Jadi meskipun FormArray kosong, itu tetap diperlukan dan oleh karena itu formulir selalu tidak valid, bahkan jika setiap kontrol yang terlihat telah diisi dengan benar.

Saya tidak menemukan bagian yang tidak valid dari formulir, karena fungsi 'findInvalidControls' saya hanya memeriksa FormControl dan bukan FormGroup / FormArray. Jadi saya memperbaruinya sedikit:

/* 
   Returns an array of invalid control/group names, or a zero-length array if 
   no invalid controls/groups where found 
*/
public findInvalidControlsRecursive(formToInvestigate:FormGroup|FormArray):string[] {
    var invalidControls:string[] = [];
    let recursiveFunc = (form:FormGroup|FormArray) => {
      Object.keys(form.controls).forEach(field => { 
        const control = form.get(field);
        if (control.invalid) invalidControls.push(field);
        if (control instanceof FormGroup) {
          recursiveFunc(control);
        } else if (control instanceof FormArray) {
          recursiveFunc(control);
        }        
      });
    }
    recursiveFunc(formToInvestigate);
    return invalidControls;
  }
Jette
sumber
3
Jawaban yang sangat berguna. Terima kasih banyak
Mikki
1
Setuju, jawaban yang sangat berguna.
nenea
24

Kontrol Angular yang tidak valid memiliki kelas CSS bernama 'ng-invalid' .

Di bawah DevTools di Chrome, pilih tab Console.

Dalam perintah tipe prompt konsol:

document.getElementsByClassName('ng-invalid')

Outputnya harus seperti ini: masukkan deskripsi gambar di sini

Dalam kasus ini, teks yang digarisbawahi adalah untuk kontrol formulir listen-address. Dan teks yang dilingkari: .ng-invalidmenunjukkan bahwa kontrol tidak valid.

Catatan: Diuji di chrome

Mwiza
sumber
2
bagi saya ini tampaknya menjadi cara paling langsung untuk menjawab pertanyaan itu.
ckapilla
2
Anda menyelamatkan saya dari menjadi gila, jika saja saya bisa membelikan Anda minuman
Adam Winnipass
3

Baik bentuk dan semua kontrol Anda memperluas kelas sudut AbstractControl. Setiap implementasi memiliki aksesor ke kesalahan validasi.

let errors = this.AddCustomerForm.errors
// errors is an instance of ValidatorErrors

Dokumen api berisi semua referensi https://angular.io/api/forms/AbstractControl

Sunting

Saya pikir aksesor kesalahan bekerja seperti ini namun tautan ke github ini menunjukkan bahwa ada beberapa orang lain yang berpikiran sama seperti yang saya lakukan https://github.com/angular/angular/issues/11530

Bagaimanapun, dengan menggunakan pengakses kontrol Anda dapat mengulangi semua formControls di formulir Anda.

Object.keys(this.AddCustomerForm.controls)
    .forEach( control => {
        //check each control here
        // if the child is a formGroup or a formArray
        // you may cast it and check it's subcontrols too
     })
LookForAngular
sumber
1
ini mengembalikan nol bahkan ada kontrol kosong
sa_
1
Ini harus mengembalikan null jika tidak ada kesalahan. Bisakah Anda memposting template Anda?
LookForAngular
Ya, ini tidak akan berfungsi, validasi berbeda diatur pada setiap kontrol formulir, yang setiap kontrol formulir berisi kesalahannya, formulir tidak. Anda perlu mengulang kontrol seperti yang telah diberikan Maximus jawabannya.
AJT82
Saya dapat mengakses kesalahan untuk setiap kontor individu seperti ini.form.controls ['Email']. Kesalahan
Nazrul Muhaimin
@ AJT_82 memang Formulir itu sendiri dapat menampilkan kesalahan jika validator telah ditetapkan untuk formGroup (periksa dokumen tentang validasi lintas bidang, yang masuk akal untuk memvalidasi pada grup dan bukan dalam kontrol)
LookForAngular
3

Sekarang, di angular 9, Anda bisa menggunakan metode markAllAsTouched () untuk menampilkan validator kontrol yang tidak valid:

this.AddCustomerForm.markAllAsTouched();
Rodrigo Jorge Baptista
sumber
Akan memberi ini +1, karena membantu saya mengetahui apa yang perlu saya ketahui --- yaitu menampilkan pesan validasi ketika pengguna belum perlu menyentuh input.
Sean Halls
1

Jika Anda tidak memiliki banyak bidang dalam formulir, cukup F12 dan arahkan kursor ke kontrol, Anda akan dapat melihat munculan dengan nilai murni / tersentuh / valid bidang- "# fieldname.form-control.ng- untouched.ng-invalid ".

darshna mishra
sumber
1

Saya pikir Anda harus mencoba menggunakan this.form.updateValueAndValidity()atau mencoba menjalankan metode yang sama di setiap kontrol.

Javi Marzán
sumber
1

coba ini

 findInvalidControls(f: FormGroup) {
    const invalid = [];
    const controls = f.controls;
    for (const name in controls) {
      if (controls[name].invalid) {
        invalid.push(name);
      }
    }
    return invalid;
  }
Trilok Singh
sumber
1

Ini akan mencatat semua nama kontrol 😊

for (let el in this.ReactiveForm.controls) {
      if (this.ReactiveForm.controls[el].errors) {
        console.log(el)
      }
 }          

Anda dapat membuat array atau string dari ini dan menampilkannya kepada pengguna

tejas n
sumber
0

Saya mengambil kebebasan untuk meningkatkan kode AngularInDepth.com -s, sehingga secara rekursif mencari input yang tidak valid dalam bentuk bersarang juga. Apakah itu disarangkan oleh FormArray-s atau FormGroup-s. Cukup masukkan formGroup tingkat atas dan itu akan mengembalikan semua FormControls yang tidak valid.

Anda mungkin dapat menepis beberapa pemeriksaan jenis "instanceof", jika Anda akan memisahkan pemeriksaan FormControl dan menambahkan fungsi array yang tidak valid ke dalam fungsi terpisah. Ini akan membuat fungsi terlihat jauh lebih bersih, tetapi saya membutuhkan opsi global, fungsi tunggal, untuk mendapatkan array datar dari semua formControls yang tidak valid dan inilah solusinya!

findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
    if ( ! _invalidControls ) _invalidControls = [];
    if ( _input instanceof FormControl  ) {
        if ( _input.invalid ) _invalidControls.push( _input );
        return _invalidControls;
    }

    if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;

    const controls = _input.controls;
    for (const name in controls) {
        let control = controls[name];
        switch( control.constructor.name )
        {
            case 'AbstractControl':
            case 'FormControl':
                if (control.invalid) _invalidControls.push( control );
                break;

            case 'FormArray':
                (<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
                break;

            case 'FormGroup':
                _invalidControls = findInvalidControls( control, _invalidControls );
                break;
        }
    }

    return _invalidControls;
}

Hanya untuk yang membutuhkan, jadi mereka tidak perlu mengkodekannya sendiri ..

Edit # 1

Itu diminta agar juga mengembalikan FormArray-s dan FormGroups yang tidak valid, jadi jika Anda membutuhkannya juga, gunakan kode ini

findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
    if ( ! _invalidControls ) _invalidControls = [];
    if ( _input instanceof FormControl  ) {
        if ( _input.invalid ) _invalidControls.push( _input );
        return _invalidControls;
    }

    if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;

    const controls = _input.controls;
    for (const name in controls) {
        let control = controls[name];
        if (control.invalid) _invalidControls.push( control );
        switch( control.constructor.name )
        {    
            case 'FormArray':
                (<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
                break;

            case 'FormGroup':
                _invalidControls = findInvalidControls( control, _invalidControls );
                break;
        }
    }

    return _invalidControls;
}
Karl Johan Vallner
sumber
1
Saya mencobanya, tetapi tidak menemukan FormGroup atau FormArray yang tidak valid ... hanya FormControl yang tidak valid. Saya membuat kesalahan yang sama ... lihat jawaban saya.
Jette
Saya memperbaiki jawaban saya, agar sesuai dengan kasus penggunaan Anda.
Karl Johan Vallner
0

Anda dapat mencatat nilai formulir console.log(this.addCustomerForm.value), itu akan menghibur semua nilai kontrol kemudian null atau bidang "" (kosong) menunjukkan kontrol tidak valid

Sohail Anwar
sumber
0

Jika Anda ingin memeriksa apakah formulir tersebut valid atau tidak, dan tidak ingin membuat perubahan kode apa pun, Anda dapat mencoba menjalankan perintah berikut di Konsol Alat Pengembang Chrome. Pastikan aplikasi angular Anda menampilkan komponen yang menghosting formulir yang dimaksud.

ng.probe(document.querySelector("app-your-component-selector-name")).componentInstance;

Jangan lupa untuk mengganti nama pemilih komponen Anda pada perintah di atas.

Perintah ini akan mencantumkan semua variabel dari komponen Anda termasuk AddCustomerForm. Sekarang jika Anda memperluas ini, Anda akan melihat daftar semua kontrol Anda. Anda kemudian dapat memperluas setiap kontrol untuk memeriksa apakah itu valid atau tidak.

RITZ XAVI
sumber
-1

Periksa nilai kontrol bentuk kosong atau nol di halaman html

Nilai kontrol formulir: {{formname.value | json}}
Uttam Kar
sumber