首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义Validator在反应式密码和确认密码匹配,获得未定义的参数到角4

自定义Validator在反应式密码和确认密码匹配,获得未定义的参数到角4
EN

Stack Overflow用户
提问于 2017-06-09 05:06:23
回答 11查看 85.1K关注 0票数 48

我正在尝试实现一个自定义验证器,以检查密码和密码确认是否相等。问题是验证器正在获取未定义的密码和confirmedPassword参数。我该怎么做呢。该函数可以工作,因为如果我将条件改为===而不是!==,则当字段相同时,它将正确抛出错误。有人知道这里的错误是哪一个吗?

signup.component.html

代码语言:javascript
复制
<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>

signup.component.ts

代码语言:javascript
复制
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);
    }
  }

}

custom-validators.ts

代码语言:javascript
复制
    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;
        }
    }
      }


    }
EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2017-06-09 05:18:28

导入{AbstractControl,FormBuilder,FormGroup,验证器}

将您的密码输入到组中,不需要使用"ngModel“。

代码语言:javascript
复制
<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>

代码语言:javascript
复制
     buildForm(): void {
            this.userForm = this.formBuilder.group({
                passwords: this.formBuilder.group({
                    password: ['', [Validators.required]],
                    confirm_password: ['', [Validators.required]],
                }, {validator: this.passwordConfirming}),

            });
        }

添加此自定义函数以验证密码和确认密码

代码语言:javascript
复制
  passwordConfirming(c: AbstractControl): { invalid: boolean } {
    if (c.get('password').value !== c.get('confirm_password').value) {
        return {invalid: true};
    }
}

当密码不匹配时显示错误

代码语言:javascript
复制
<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>
票数 59
EN

Stack Overflow用户

发布于 2017-06-09 05:16:48

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

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

我在一个应用程序中做了这样的事情来验证密码匹配。

代码语言:javascript
复制
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字段作为参数,并将该字段的值与Credentials FormGroupPassword字段的值进行比较。

HTML中,确保删除ng-model

代码语言:javascript
复制
<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">

希望这能有所帮助!

票数 19
EN

Stack Overflow用户

发布于 2018-04-03 10:35:16

有两种类型的验证器:FormGroup验证器FormControl验证器。要验证两个密码匹配,您必须添加一个FormGroup验证器。以下是我的例子:

注意: this.fb是注入的FormBuilder

代码语言:javascript
复制
this.newAccountForm = this.fb.group(
  {
    newPassword: ['', [Validators.required, Validators.minLength(6)]],
    repeatNewPassword: ['', [Validators.required, Validators.minLength(6)]],
  }, 
  {validator: this.passwordMatchValidator}
);

passwordMatchValidator(frm: FormGroup) {
  return frm.controls['newPassword'].value === frm.controls['repeatNewPassword'].value ? null : {'mismatch': true};
}

在殿中:

代码语言:javascript
复制
<div class="invalid-feedback" *ngIf="newAccountForm.errors?.mismatch && (newAccountForm.controls['repeatNewPassword'].dirty || newAccountForm.controls['repeatNewPassword'].touched)">
  Passwords don't match.
</div>

这里的关键点是将FormGroup验证器作为第二个参数添加到组方法中。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44449673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档