密码反应形式的自定义验证器并确认密码匹配将未定义的参数获取到 Angular 4

新手上路,请多包涵

我正在尝试实现一个自定义验证器来检查密码和密码确认是否相等。问题是验证器正在获取未定义的密码和 confirmedPassword 参数。我如何使这项工作。该函数起作用是因为如果我将条件更改为 === 而不是 !== 它会在字段相同时正确抛出错误。有谁知道这里的错误是什么?

注册.component.html

 <div class="col-md-7 col-md-offset-1 col-sm-7">
  <div class="block">
    <div class="well">
        <form (onSubmit)="onSubmit()" [formGroup]="signUpForm">
          <div class="form-group">
            <label for="username" class="control-label">Nombre de usuario:</label>
            <input type="text" class="form-control" formControlName="username"  title="Please enter your username" placeholder="username">
            <p class="help-block" *ngIf="signUpForm.get('username').hasError('required') && signUpForm.get('username').touched">El nombre de usuario es obligatorio</p>
            <p class="help-block" *ngIf="signUpForm.get('username').hasError('minlength') && signUpForm.get('username').touched">El nombre de usuario debe tener al menos 6 caracteres</p>
            <p class="help-block" *ngIf="signUpForm.get('username').hasError('maxlength') && signUpForm.get('username').touched">El nombre de usuario debe tener menos de 15 caracteres</p>
          </div>
          <div class="form-group">
            <label for="email" class="control-label">E-mail:</label>
            <input class="form-control" formControlName="email" title="Please enter your email" placeholder="example@gmail.com">
            <p class="help-block" *ngIf="signUpForm.get('email').hasError('required') && signUpForm.get('email').touched">La dirección de email es obligatoria</p>
            <p class="help-block" *ngIf="signUpForm.get('email').hasError('email') && signUpForm.get('email').touched">Debe ingresar una dirección de correo válida</p>
          </div>
          <div class="form-group">
            <label for="password" class="control-label">Contraseña:</label>
            <input type="password" class="form-control" formControlName="password" title="Please enter your password" [(ngModel)]="password">
            <p class="help-block" *ngIf="signUpForm.get('password').hasError('required') && signUpForm.get('password').touched">Debe ingresar una contraseña</p>
          </div>
          <div class="form-group">
            <label for="confirmedPassword" class="control-label">Confirmar Contraseña:</label>
            <input type="password" class="form-control" formControlName="confirmedPassword"  title="Please re-enter your password" [(ngModel)]="confirmedPassword">
            <p class="help-block" *ngIf="signUpForm.get('confirmedPassword').hasError('required') && signUpForm.get('confirmedPassword').touched">La confirmación de contraseña no puede estar vacía</p>
            <p class="help-block" *ngIf="signUpForm.get('confirmedPassword').hasError('passwordMismatch') && signUpForm.get('confirmedPassword').touched">Las contraseñas no coinciden</p>
          </div>
          <button type="submit" class="btn btn-success" [disabled]="!signUpForm.valid">Registrarse</button>
          <a routerLink="/signin" class="btn btn-default" style="">Ya tenes usuario? Logueate</a> {{ creationMessage }}
        </form>

      </div>

  </div>
</div>

注册.component.ts

 import { Component, OnInit, ViewChild, Input } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { CustomValidators } from '../../shared/custom-validators';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.sass']
})
export class SignupComponent implements OnInit {

  signUpForm: FormGroup;
  user = {
    username: '',
    email: '',
    password: ''
  };
  submitted = false;
  @Input() password='';
  @Input() confirmedPassword='';

  constructor() { }

  ngOnInit() {

    this.signUpForm = new FormGroup({
      'username': new FormControl(null, [Validators.required, Validators.minLength(6), Validators.maxLength(15)]),
      'email': new FormControl(null, [Validators.required, Validators.email, Validators.minLength(5)]),
      'password': new FormControl(null, [Validators.required]),
      'confirmedPassword': new FormControl(null, [Validators.required, CustomValidators.passwordsMatch(this.password,this.confirmedPassword).bind(this)])
    });
  }

  onSubmit() {
    if (this.signUpForm.valid) {
      console.log(this.signUpForm.value);
    }
  }

}

自定义验证器.ts

     import { FormControl } from '@angular/forms';

    export class CustomValidators{

    public static passwordsMatch(password: string, confirmedPassword: string) {

     return (control: FormControl) : { [s: string]: boolean } =>{
       //getting undefined values for both variables
       console.log(password,confirmedPassword);
        //if I change this condition to === it throws the error if the
//  two fields are the same, so this part works
        if (password !== confirmedPassword) {
          return { 'passwordMismatch': true }
        } else {
          //it always gets here no matter what
          return null;
        }
    }
      }

    }

原文由 Juan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 349
2 个回答

从中导入 {AbstractControl、FormBuilder、FormGroup、Validators}

将您的密码输入到组中,无需使用“ngModel”。

 <div class="form-group row" formGroupName="passwords">
  <div class="form-group">
     <label for="password" class="control-label">Contraseña:</label>
     <input type="password" class="form-control" formControlName="password" title="Please enter your password">
     <p class="help-block" *ngIf="signUpForm.get('password').hasError('required') && signUpForm.get('password').touched">Debe ingresar una contraseña</p>
  </div>
  <div class="form-group">
     <label for="confirmedPassword" class="control-label">Confirmar Contraseña:</label>
     <input type="password" class="form-control" formControlName="confirmedPassword"  title="Please re-enter your password">
     <p class="help-block" *ngIf="signUpForm.get('confirmedPassword').hasError('required') && signUpForm.get('confirmedPassword').touched">Password must be required</p>
     <p class="help-block" *ngIf="signUpForm.get('confirmedPassword').hasError('passwordMismatch') && signUpForm.get('confirmedPassword').touched">password does not match</p>
  </div>

      buildForm(): void {
            this.userForm = this.formBuilder.group({
                passwords: this.formBuilder.group({
                    password: ['', [Validators.required]],
                    confirm_password: ['', [Validators.required]],
                }, {validator: this.passwordConfirming}),

            });
        }

添加此自定义功能以验证密码和确认密码

  passwordConfirming(c: AbstractControl): { invalid: boolean } {
    if (c.get('password').value !== c.get('confirm_password').value) {
        return {invalid: true};
    }
}

密码不匹配时显示错误

<div style='color:#ff7355' *ngIf="userForm.get(['passwords','password']).value != userForm.get(['passwords','confirm_password']).value && userForm.get(['passwords','confirm_password']).value != null">
  Password does not match</div>

原文由 Shailesh Ladumor 发布,翻译遵循 CC BY-SA 4.0 许可协议

问题是您 将反应式表单模块与输入方法混合在一起。这导致您在将值传递给验证器时得到 undefined

使用反应形式时,您不需要绑定到 ng-model 。相反,您应该从 FormGroup 的实例访问字段的值。

我在应用程序中做了类似的事情来验证密码匹配。

 public Credentials: FormGroup;

ngOnInit() {
    this.Credentials = new FormGroup({});
    this.Credentials.addControl('Password', new FormControl('', [Validators.required]));
    this.Credentials.addControl('Confirmation', new FormControl(
        '', [Validators.compose(
            [Validators.required, this.validateAreEqual.bind(this)]
        )]
    ));
}

private validateAreEqual(fieldControl: FormControl) {
    return fieldControl.value === this.Credentials.get("Password").value ? null : {
        NotEqual: true
    };
}

请注意,验证器需要一个 FormControl 字段作为参数,并将该字段的值与 Password 的字段的值进行比较 —a5d263a192e2f63a3954da-41db-f -41db FormGroup Credentials ---

HTML 确保删除 ng-model

 <input type="password" class="form-control" formControlName="confirmedPassword"  title="Please re-enter your password" >
<!-- AND -->
<input type="password" class="form-control" formControlName="password" title="Please enter your password">

希望这可以帮助!

原文由 Daniel Ormeño 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题