Geçersiz kontroller açısal 4 reaktif formda nasıl bulunur


92

Aşağıdaki gibi Angular'da reaktif bir formum var:

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 false döndürür, ancak her şey iyi görünüyor.

Kontrol koleksiyonundaki status özelliğini kontrol ederek bulmaya çalıştım. Ama acaba geçersiz olanları bulmanın ve kullanıcıya göstermenin bir yolu var mı?


Yalnızca hatalı alanları görüntülemek istiyorsanız, geçersiz alanları vurgulamak veya renklendirmek için css kullanabilirsiniz. Her geçersiz alanın, sınıf listesine eklenen bir "ng-geçersiz" sınıfı vardır
LookForAngular

Yanıtlar:


176

Her kontrolü yineleyebilir ve durumu kontrol edebilirsiniz:

    public findInvalidControls() {
        const invalid = [];
        const controls = this.AddCustomerForm.controls;
        for (const name in controls) {
            if (controls[name].invalid) {
                invalid.push(name);
            }
        }
        return invalid;
    }

1
bunun için teşekkürler ama bunu denedim ve bu hiçbir şey döndürmese bile formum hala geçersiz, bu garip. Demek istediğim bu kod iyi görünüyor ama neden form.valid döner yanlış
sa_

sana ne döndürüyor findInvalidControls()?
Max Koretskyi

1
hiçbir şey döndürmez, geçersiz boştur. Hata ayıklama izleme ekranında tek tek kontrol ettim, tüm kontroller geçerli ama this.AddCustomerForm.valid hala false döndürüyor.
sa_

Sanırım öğrendim. bir e-posta alanı ve normal ifade var ama bir şekilde kontrolün durumu
BEKLEMEDE

7
@ AngularInDepth.com - denetimlerden biri bir form grubuysa, işleviniz geçersiz olan belirli bir form denetimini değil geçersiz form grubunu döndürecektir
john Smith

36

Bu sorunla az önce mücadele ettim: Her form alanı geçerli, ancak yine de formun kendisi geçersiz.

Denetimlerin dinamik olarak eklendiği / kaldırıldığı bir FormArray üzerinde 'Validator.required' ayarladığım ortaya çıktı. Dolayısıyla, FormArray boş olsa bile, yine de gerekliydi ve bu nedenle, her görünür denetim doğru şekilde doldurulmuş olsa bile form her zaman geçersizdi.

Formun geçersiz bölümünü bulamadım çünkü 'findInvalidControls' işlevim FormGroup / FormArray'i değil yalnızca FormControl'leri kontrol etti. Bu yüzden biraz güncelledim:

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

3
İnanılmaz derecede faydalı cevap. Çok teşekkür ederim
Mikki

1
Katılıyorum, çok faydalı cevap.
nenea

24

Geçersiz bir Açısal denetim, 'ng-geçersiz' adlı CSS sınıfına sahiptir .

Chrome'da DevTools altında, Konsol sekmesini seçin.

Konsolda komut istemi yazın:

document.getElementsByClassName('ng-invalid')

Çıktı şuna benzer olmalıdır: görüntü açıklamasını buraya girin

Bu durumda, altı çizili metin form kontrolü içindir listen-address. Ve daire içine alınmış metin: .ng-invalidkontrolün geçersiz olduğunu gösterir.

Not: Chrome'da test edildi


2
bu bana soruyu yanıtlamanın en doğrudan yolu gibi görünüyor.
ckapilla

2
Beni delirmekten kurtardın, keşke sana bir içki ısmarlayabilseydim
Adam Winnipass

3

Hem formlar hem de tüm denetimleriniz AbstractControl açısal sınıfını genişletir. Her uygulamanın, doğrulama hatalarına bir erişimcisi vardır.

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

Api belgeleri tüm referansları içerir: https://angular.io/api/forms/AbstractControl

Düzenle

Hata erişimcisinin bu şekilde çalıştığını düşündüm, ancak bu github bağlantısı, https://github.com/angular/angular/issues/11530 yaptığımla aynı düşünen başka insanların olduğunu gösteriyor

Her durumda, denetim erişimcisini kullanarak formunuzdaki tüm formControls üzerinde yineleme yapabilirsiniz.

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

1
bu boş kontroller olsa bile boş döndürür
sa_

1
Hata olmadığında boş döndürmelidir. Şablonunuzu gönderebilir misiniz?
LookForAngular

Evet, bu işe yaramaz, her bir form kontrolünde ayarlanan farklı doğrulamalar, her form kontrolünde kendi hataları var, formda değil. Maximus'un cevap verdiği gibi kontrolleri tekrarlamanız gerekiyor.
AJT82

This.form.controls ['Email'] gibi her bir contorls için hatalara erişebilirim. Error
Nazrul Muhaimin

@ AJT_82, formGroup için bir doğrulayıcı ayarlanmışsa, Formun kendisi hatalar gösterebilir (çapraz alan doğrulamasıyla ilgili belgeleri kontrol edin, bu, grup üzerinde doğrulamak için mantıklıdır, kontrolde değil)
LookForAngular

3

Şimdi, açısal 9'da, geçersiz kontrol doğrulayıcılarını göstermek için markAllAsTouched () yöntemini kullanabilirsiniz:

this.AddCustomerForm.markAllAsTouched();

Buna bir +1 verecek, çünkü bilmem gereken şeyi bulmama yardımcı oldu - bu, kullanıcının girişlere dokunması gerekmediğinde doğrulama mesajlarını göstermekti.
Sean Halls

1

Formda çok fazla alanınız yoksa, sadece F12 ve imleci kontrolün üzerine getirebilirsiniz, alanın bozulmamış / dokunulmuş / geçerli değerlerinin bulunduğu açılır pencereyi görebilirsiniz - "# alanadı.form-kontrol.ng- untouched.ng-geçersiz ".


1

this.form.updateValueAndValidity()Kontrollerin her birinde aynı yöntemi kullanmayı denemeniz veya denemeniz gerektiğini düşünüyorum .


1

bunu dene

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

1

Bu, kontrollerin tüm adlarını kaydedecektir 😊

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

bundan bir dizi veya dize oluşturabilir ve kullanıcıya gösterebilirsiniz


0

AngularInDepth.com kodunu iyileştirme özgürlüğünü aldım , böylece iç içe geçmiş formlarda geçersiz girdileri yinelemeli olarak arar. FormArray-s veya FormGroup-s tarafından yuvalanması. Sadece en üst düzey formGroup'u girin ve geçersiz olan tüm FormControl'leri döndürür.

FormControl denetimini ve geçersiz dizi işlevselliğine eklemeyi ayrı bir işleve ayırırsanız, "instanceof" türü denetimlerinin bazılarını gözden geçirebilirsiniz. Bu, işlevin çok daha temiz görünmesini sağlardı, ancak tüm geçersiz formControls'lerin düz bir dizisini elde etmek için global, tek işlevli bir seçeneğe ihtiyacım vardı ve çözüm bu!

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

Sadece ihtiyacı olanlar için, böylece kendileri kodlamak zorunda kalmazlar ..

1 Numaralı Düzenle

Ayrıca geçersiz FormArray ve FormGroups döndürmesi istendi, bu nedenle buna da ihtiyacınız varsa, bu kodu kullanın

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

1
Denedim, ancak herhangi bir geçersiz FormGroup veya FormArray bulamadı ... sadece geçersiz FormControl's. Ben de aynı hatayı yaptım ... cevabıma bakın.
Jette

Cevabımı kullanım durumunuza uyacak şekilde geliştirdim.
Karl Johan Vallner

0

formun değerini kaydedebilirsiniz console.log(this.addCustomerForm.value), tüm kontrolün değerini konsolide eder ve ardından boş veya "" (boş) alanlar geçersiz kontrolleri gösterir


0

Formun geçerli olup olmadığını kontrol etmek ve herhangi bir kod değişikliği yapmak istemiyorsanız, Chrome Developer Tool Console'da aşağıdaki komutu çalıştırmayı deneyebilirsiniz. Lütfen açısal uygulamanızın söz konusu formu barındıran bileşeni görüntülediğinden emin olun.

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

Yukarıdaki komutta bileşen seçici adınızı değiştirmeyi unutmayın.

Bu komut, bileşeninizdeki tüm değişkenleri listeleyecektir AddCustomerForm. Şimdi bunu genişletirseniz, tüm kontrollerinizin listesini göreceksiniz. Ardından, geçerli olup olmadığını kontrol etmek için her bir kontrolü genişletebilirsiniz.


-1

Html sayfasında boş veya boş form kontrol değerini kontrol edin

Form denetimleri değeri: {{formname.value | json}}
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.