Açısal form alanını el ile geçersiz olarak nasıl ayarlayabilirim?


190

Bir giriş formu üzerinde çalışıyorum ve kullanıcı geçersiz kimlik bilgileri girerse, hem e-posta hem de parola alanlarını geçersiz olarak işaretlemek ve oturum açma işleminin başarısız olduğunu belirten bir ileti görüntülemek istiyoruz. Bu alanları gözlemlenebilir bir geri aramadan geçersiz olacak şekilde nasıl ayarlayabilirim?

Şablon:

<form #loginForm="ngForm" (ngSubmit)="login(loginForm)" id="loginForm">
  <div class="login-content" fxLayout="column" fxLayoutAlign="start stretch">
    <md-input-container>
      <input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email">
    </md-input-container>
    <md-input-container>
      <input mdInput placeholder="Password" type="password" name="password" required [(ngModel)]="password">
    </md-input-container>
    <p class='error' *ngIf='loginFailed'>The email address or password is invalid.</p>
    <div class="extra-options" fxLayout="row" fxLayoutAlign="space-between center">
     <md-checkbox class="remember-me">Remember Me</md-checkbox>
      <a class="forgot-password" routerLink='/forgot-password'>Forgot Password?</a>
    </div>
    <button class="login-button" md-raised-button [disabled]="!loginForm.valid">SIGN IN</button>
     <p class="note">Don't have an account?<br/> <a [routerLink]="['/register']">Click here to create one</a></p>
   </div>
 </form>

Giriş yöntemi:

 @ViewChild('loginForm') loginForm: HTMLFormElement;

 private login(formData: any): void {
    this.authService.login(formData).subscribe(res => {
      alert(`Congrats, you have logged in. We don't have anywhere to send you right now though, but congrats regardless!`);
    }, error => {
      this.loginFailed = true; // This displays the error message, I don't really like this, but that's another issue.
      this.loginForm.controls.email.invalid = true;
      this.loginForm.controls.password.invalid = true; 
    });
  }

Girişler geçersiz bayrağı true olarak ayarlamaya ek olarak email.validbayrağı false olarak ayarlamayı ve loginForm.invalidde true olarak ayarlamayı denedim . Bunların hiçbiri girişlerin geçersiz durumlarını göstermesine neden olmaz.


Arka ucunuz açısaldan farklı bir bağlantı noktasında mı? Eğer öyleyse, bu bir CORS sorunu olabilir. Arka uç için hangi çerçeveyi kullanıyorsunuz?
Mike3355

setErrosYöntemi kullanabilirsiniz . İpuçları: Bileşen dosyanıza gerekli doğrulayıcıyı eklemelisiniz. Ayrıca ngModel'i reaktif formlarla kullanmanın özel bir nedeni var mı?
developer033

@ developer033 buradaki partiye biraz geç kaldı, ancak bunlar Reaktif Form gibi değil, Şablon odaklı bir form gibi görünüyor.
thenetimp

Yanıtlar:


261

bileşen içinde:

formData.form.controls['email'].setErrors({'incorrect': true});

ve HTML olarak:

<input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email"  #email="ngModel">
<div *ngIf="!email.valid">{{email.errors| json}}</div>

13
Daha sonra hatayı nasıl silebilirsiniz? setErrors({'incorrect': false})veya setErrrors({})benim için çalışmıyor
Robouste

3
Tüm reaktif formu alanları sıfırlamak yerine geçerli veya geçersiz olarak ayarlayabilir miyim?
xtremist

29
@Robouste hataları manuel olarak kaldırabilirsinizsetErrrors(null)
Idrees Khan

6
Bu yanıta ek olarak: bu kod, formData.form.controls['email'].markAsTouched();@ M.Farahmand'ın belirttiği gibi benim için çalışmaz . Kullanımı setErrors({'incorrect': true})sadece set ng-invalidgirişi için css sınıfını. Umarım birine yardımcı olur.
Barabas

4
Ve "zorunlu" gibi daha fazla doğrulayıcı varsa - setErrors (null) bu hatayı siliyor mu?
Please_Dont_Bully_Me_SO_Lords

88

Julia Passynkova'nın cevabına ekleme

Bileşendeki doğrulama hatasını ayarlamak için:

formData.form.controls['email'].setErrors({'incorrect': true});

Bileşendeki doğrulama hatasını ayarlamak için:

formData.form.controls['email'].setErrors(null);

nullTüm hataların üzerine yazılacağından , hataları kullanarak dikkatli olmamaya dikkat edin . Etrafında biraz tutmak istiyorsanız, önce diğer hataların varlığını kontrol etmeniz gerekebilir:

if (isIncorrectOnlyError){
   formData.form.controls['email'].setErrors(null);
}

3
FormData.form.controls ['email'] gibi bir doğrulama kullanarak doğrulama hatasını ayarlamak mümkün mü? SetErrors ({'wrong': false});
rudrasiva86

1
Reaktif formlar ne olacak?
seidme

26

Aramaya çalışıyordum setErrors()Şablon formunda bir ngModelChange işleyicisi içinde . Ben bir kene bekledi kadar işe yaramadı setTimeout():

şablonu:

<input type="password" [(ngModel)]="user.password" class="form-control" 
 id="password" name="password" required (ngModelChange)="checkPasswords()">

<input type="password" [(ngModel)]="pwConfirm" class="form-control"
 id="pwConfirm" name="pwConfirm" required (ngModelChange)="checkPasswords()"
 #pwConfirmModel="ngModel">

<div [hidden]="pwConfirmModel.valid || pwConfirmModel.pristine" class="alert-danger">
   Passwords do not match
</div>

bileşen:

@ViewChild('pwConfirmModel') pwConfirmModel: NgModel;

checkPasswords() {
  if (this.pwConfirm.length >= this.user.password.length &&
      this.pwConfirm !== this.user.password) {
    console.log('passwords do not match');
    // setErrors() must be called after change detection runs
    setTimeout(() => this.pwConfirmModel.control.setErrors({'nomatch': true}) );
  } else {
    // to clear the error, we don't have to wait
    this.pwConfirmModel.control.setErrors(null);
  }
}

Bunun gibi bana reaktif formları tercih ediyorlar.


Cannot find name 'NgModel'.@ViewChild('pwConfirmModel') pwConfirmModel: NgModel;Bu sorun için herhangi bir düzeltme satırı hatası
Derin 3015

SetTimeOuts'u kullanmak zorunda kalmanın nesi var? Bunu fark ettim ve kontroller hemen kendilerini güncellemiyor gibi görünüyor. Bu, bu sınırlamaya geçici bir çözüm bulmak için bir sürü hileli kod getiriyor.
Jake Shakesworth

Teşekkürler. Biliyordum setErrorsama kullanılana kadar işe yaramadısetTimeout
Sampgun

25

Kontrol adının setErrors () mat önekiyle başlayan yeni malzeme 2 sürümünde, bunun yerine Juila'nın cevabı şu şekilde değiştirilebilir:

formData.form.controls['email'].markAsTouched();

1

İşte bir örnek:

MatchPassword(AC: FormControl) {
  let dataForm = AC.parent;
  if(!dataForm) return null;

  var newPasswordRepeat = dataForm.get('newPasswordRepeat');
  let password = dataForm.get('newPassword').value;
  let confirmPassword = newPasswordRepeat.value;

  if(password != confirmPassword) {
    /* for newPasswordRepeat from current field "newPassword" */
    dataForm.controls["newPasswordRepeat"].setErrors( {MatchPassword: true} );
    if( newPasswordRepeat == AC ) {
      /* for current field "newPasswordRepeat" */
      return {newPasswordRepeat: {MatchPassword: true} };
    }
  } else {
    dataForm.controls["newPasswordRepeat"].setErrors( null );
  }
  return null;
}

createForm() {
  this.dataForm = this.fb.group({
    password: [ "", Validators.required ],
    newPassword: [ "", [ Validators.required, Validators.minLength(6), this.MatchPassword] ],
    newPasswordRepeat: [ "", [Validators.required, this.MatchPassword] ]
  });
}

Bu "hacky" olabilir, ama Açısal Malzeme Giriş hataları ile çalışmak için özel bir ErrorStateMatcher ayarlamak zorunda değilsiniz çünkü bunu seviyorum!
David Melin

1

Reaktif formumda, başka bir alan işaretliyse bir alanı geçersiz olarak işaretlemem gerekiyordu. Sürüm 7'de aşağıdakileri yaptım:

    const checkboxField = this.form.get('<name of field>');
    const dropDownField = this.form.get('<name of field>');

    this.checkboxField$ = checkboxField.valueChanges
        .subscribe((checked: boolean) => {
            if(checked) {
                dropDownField.setValidators(Validators.required);
                dropDownField.setErrors({ required: true });
                dropDownField.markAsDirty();
            } else {
                dropDownField.clearValidators();
                dropDownField.markAsPristine();
            }
        });

Yukarıda, kutuyu işaretlediğimde açılır listeyi gerektiği gibi ayarlar ve kirli olarak işaretler. Böyle işaretlemezseniz, formu göndermeye veya onunla etkileşime geçmeye çalışana kadar geçersiz (hatalı) olmaz.

Onay kutusu yanlış (işaretlenmemiş) olarak ayarlanırsa, açılır menüde gerekli doğrulayıcıyı temizler ve bozulmamış bir duruma sıfırlarız.

Ayrıca - alan değişikliklerini izlemekten çıkmayı unutmayın!


1

ViewChild 'type' öğesini NgForm olarak şu şekilde değiştirebilirsiniz:

@ViewChild('loginForm') loginForm: NgForm;

Ve sonra kontrollerinize @Julia'nın bahsettiği şekilde bakın:

 private login(formData: any): void {
    this.authService.login(formData).subscribe(res => {
      alert(`Congrats, you have logged in. We don't have anywhere to send you right now though, but congrats regardless!`);
    }, error => {
      this.loginFailed = true; // This displays the error message, I don't really like this, but that's another issue.

      this.loginForm.controls['email'].setErrors({ 'incorrect': true});
      this.loginForm.controls['password'].setErrors({ 'incorrect': true});
    });
  }

Hataların null olarak ayarlanması kullanıcı arayüzündeki hataları temizler:

this.loginForm.controls['email'].setErrors(null);

0

Geç olmasına rağmen aşağıdaki çözüm işe yaradı beni.

    let control = this.registerForm.controls['controlName'];
    control.setErrors({backend: {someProp: "Invalid Data"}});
    let message = control.errors['backend'].someProp;

-9

Birim testi için:

spyOn(component.form, 'valid').and.returnValue(true);
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.