각도 양식 필드를 유효하지 않은 것으로 수동으로 설정하려면 어떻게해야합니까?


190

로그인 양식을 작성 중이며 사용자가 유효하지 않은 자격 증명을 입력하면 이메일 및 비밀번호 필드를 모두 유효하지 않은 것으로 표시하고 로그인이 실패했다는 메시지를 표시하려고합니다. 이러한 필드를 관찰 가능한 콜백에서 유효하지 않게 설정하려면 어떻게해야합니까?

주형:

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

로그인 방법 :

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

입력 무효 플래그를 true로 설정하는 것 외에도 email.valid플래그를 false로 설정하고 loginForm.invalid를 true로 설정 하려고 시도했습니다 . 이들 중 어느 것도 입력에 유효하지 않은 상태를 표시하지 않습니다.


백엔드가 각도와 다른 포트에 있습니까? 그렇다면 CORS 문제 일 수 있습니다. 백엔드에 어떤 프레임 워크를 사용하고 있습니까?
Mike3355

setErros방법 을 사용할 수 있습니다 . 팁 : 구성 요소 파일에 필수 유효성 검증기를 추가해야합니다. 또한 반응성 양식과 함께 ngModel을 사용해야하는 특별한 이유가 있습니까?
developer033

@ developer033 여기 파티에 조금 늦었지만 반응 형은 아니지만 템플릿 중심 양식입니다.
thenetimp

답변:


261

구성 요소에서 :

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

그리고 HTML에서 :

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

13
그리고 나중에 오류를 어떻게 제거합니까? setErrors({'incorrect': false})또는 setErrrors({})나를 위해 일하고 있지 않습니다
Robouste

3
필드를 재설정하는 대신 전체 반응 형을 유효 또는 무효로 설정할 수 있습니까?
xtremist

29
@Robouste 당신은 수동으로 오류를 제거 할 수 있습니다setErrrors(null)
Idrees Khan

6
이 답변 formData.form.controls['email'].markAsTouched();외에도이 코드는 아래 언급 된 @ M.Farahmand 없이는 작동하지 않습니다 . 사용 setErrors({'incorrect': true})만 설정 ng-invalid입력을 위해 CSS 클래스를. 누군가에게 도움이되기를 바랍니다.
Barabas

4
그리고 "필수"와 같은 검증자가 더 있다면-setErrors (null)는 그 에러를 삭제합니까?
Please_Dont_Bully_Me_SO_Lords

88

Julia Passynkova의 답변에 추가

구성 요소에서 유효성 검증 오류를 설정하려면 다음을 수행하십시오.

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

구성 요소에서 유효성 검증 오류를 설정 해제하려면 다음을 수행하십시오.

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

사용하여 오류를 설정 해제하면 null모든 오류를 덮어 쓰므로주의하십시오 . 주위를 유지하려면 먼저 다른 오류가 있는지 확인해야 할 수 있습니다.

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

3
formData.form.controls [ 'email']. setErrors ({ 'incorrect': false})와 같은 것을 사용하여 유효성 검사 오류를 설정 해제 할 수 있습니까?
rudrasiva86

1
반응성 형태는 어떻습니까?
seidme

26

setErrors()템플릿 형식으로 ngModelChange 핸들러 내부 를 호출하려고했습니다 . 하나의 진드기를 기다릴 때까지 작동하지 않았습니다.setTimeout() .

주형:

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

구성 요소:

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

이와 같은 문제는 반응 형을 선호합니다.


Cannot find name 'NgModel'.@ViewChild('pwConfirmModel') pwConfirmModel: NgModel;이 문제에 대한 모든 수정 프로그램을위한 오류
Deep 3015

setTimeOuts를 사용해야하는 것은 무엇입니까? 컨트롤이 즉시 업데이트되지 않는 것처럼이 사실을 알았습니다. 이것은이 제한을 해결하기 위해 많은 해키 코드를 소개합니다.
Jake Shakesworth

감사. 알았지 setErrors만 사용하기 전까지는 작동하지 않았습니다.setTimeout
Sampgun

25

제어 이름이 매트 접두어로 setErrors ()로 시작하는 재료 2의 새 버전에서는 Juila의 답변을 다음과 같이 변경할 수 있습니다.

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

1

다음은 작동하는 예입니다.

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

이것은 "hacky"일 수 있지만 Angular Material Input 오류와 함께 작동하기 위해 사용자 정의 ErrorStateMatcher를 설정할 필요가 없기 때문에 좋아합니다!
David Melin

1

내 반응성 양식에서 다른 필드를 확인한 경우 필드를 유효하지 않은 것으로 표시해야했습니다. ng 버전 7에서는 다음을 수행했습니다.

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

위의 상자를 선택하면 드롭 다운이 필요에 따라 설정되고 더티로 표시됩니다. 그렇게 표시하지 않으면 양식을 제출하거나 상호 작용할 때까지 유효하지 않습니다 (오류).

확인란이 false (체크되지 않은)로 설정되면 드롭 다운에서 필요한 유효성 검사기를 지우고 원래 상태로 다시 설정합니다.

또한-현장 변경 모니터링을 취소하십시오!


1

다음과 같이 viewChild 'type'을 NgForm으로 변경할 수도 있습니다.

@ViewChild('loginForm') loginForm: NgForm;

그리고 @Julia가 언급 한 것과 같은 방식으로 컨트롤을 참조하십시오.

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

오류를 null로 설정하면 UI의 오류가 지워집니다.

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

0

비록 늦었지만 다음과 같은 해결책이 효과가있었습니다.

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

-9

단위 테스트의 경우 :

spyOn(component.form, 'valid').and.returnValue(true);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.