Angular 2表单验证重复密码

Angular 2表单验证重复密码,angular,Angular,请参阅此部分,了解将验证器中的字段与Angular 2进行比较的情况。不幸的是,Angular 2发生了一些变化,所以解决方案似乎不再有效。这是我的密码: import{IonicApp,Page,NavController,NavParams}来自'ionic/ionic' 从'angular2/core'导入{Component} 从“angular2/common”导入{FORM_提供程序、FormBuilder、验证器} 从“../../components/control messag

请参阅此部分,了解将验证器中的字段与Angular 2进行比较的情况。不幸的是,Angular 2发生了一些变化,所以解决方案似乎不再有效。这是我的密码:

import{IonicApp,Page,NavController,NavParams}来自'ionic/ionic'
从'angular2/core'导入{Component}
从“angular2/common”导入{FORM_提供程序、FormBuilder、验证器}
从“../../components/control messages”导入{ControlMessages}
从“../../services/validation service”导入{ValidationService}
@页面({
templateUrl:'build/pages/account/register.html',
指令:[控制消息]
})
导出类注册表{
构造函数(导航:导航控制器,专用生成器:FormBuilder){
this.nav=nav
this.registerForm=this.builder.group({
“名称”:[“”,验证程序。必需],
“电子邮件”:['',Validators.compose([Validators.required,ValidationService.emailValidator]),
“密码”:[“”,验证程序。必需],
“重复”:['',此.customValidator]
}
)        
}
寄存器(){
警报(this.registerForm.value.password)
}
专用客户验证程序(控制){
//console.log(this.registerForm.value.password)
//返回{isEqual:control.value==this.registerForm.value.password}
返回真值
}
}
我的html:


名称
电子邮件
密码
确认密码
登记
已拥有帐户,请登录
但不幸的是,我无法访问验证函数中的
密码
值。如果我取消注释console.log(this.registerForm.value.password),则会收到以下错误消息:

异常:TypeError:无法读取未定义的属性“值”


有什么想法吗?谢谢。

我发现您的代码中有几个问题。您尝试在validator函数中使用
this
关键字,但这与组件的实例不对应。这是因为您在将函数设置为验证器函数时引用了该函数

此外,可以在
value
属性中达到与控件关联的值

也就是说,我认为将两个字段一起验证的正确方法是创建一个组并在其中关联一个验证器:

import { FormBuilder, Validators } from '@angular/forms';
...
constructor(private fb: FormBuilder) { // <--- inject FormBuilder
  this.createForm();
}
createForm() {
  this.registerForm = this.fb.group({
    'name' : ['', Validators.required],
    'email': ['', [Validators.required, Validators.email] ],
    'passwords': this.fb.group({
      password: ['', Validators.required],
      repeat:   ['', Validators.required]
    }, {validator: this.matchValidator})
  });    
}
有关更多详细信息,请参阅此答案:

编辑

要显示错误,只需使用以下命令:

<span *ngIf="!registerForm.passwords.valid" class="help-block text-danger">
  <div *ngIf="registerForm.passwords?.errors?.mismatch">
    The two passwords aren't the same
  </div>
</span>

这两个密码不一样

此外,从表格0.2.0的angular 2 rc4开始,需要调用用于包含分组输入的组名的标记和属性来防止错误

<div formGroupName="passwords">group input fields here... </div>
此处分组输入字段。。。

如果您使用的是RC.5,但找不到ControlGroup,可以尝试使用FormGroup。你可以从我的回答中了解更多:


将密码保存到实例变量中

    password = new FormControl('', [Validators.required]);
然后在您的表单组中使用它

        this.registrationForm = this.fb.group({
        'email': ['', [
            Validators.required,
            NGValidators.isEmail,
        ]
        ],
        'password': this.password,
        'password2': ['', [Validators.required, this.passwordMatch]]
    });
import {AbstractControl} from '@angular/forms';

export class PasswordValidation {

    static MatchPassword(AC: AbstractControl) {
       const formGroup = AC.parent;
       if (formGroup) {
            const passwordControl = formGroup.get('Password'); // to get value in input tag
            const confirmPasswordControl = formGroup.get('Confirm'); // to get value in input tag

            if (passwordControl && confirmPasswordControl) {
                const password = passwordControl.value;
                const confirmPassword = confirmPasswordControl.value;
                if (password !== confirmPassword) { 
                    return { matchPassword: true };
                } else {
                    return null;
                }
            }
       }

       return null;
    }
}
所以函数看起来像这样

 private passwordMatch() {
        let that = this;
        return (c: FormControl) =>
        {
            return (c.value == that.password.value) ? null : {'passwordMatch': {valid: false}};
        }
    }
我知道这不是最好的解决方案,但它很有效

通过使用此库,您可以轻松做到:

this.form = new ValidationManager({
  'password'    : 'required|rangeLength:8,50',
  'repassword'  : 'required|equalTo:password'
});

我只想发布我的解决方案:

this.authorizationSettings = formBuilder.group({
      currentPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])],
      newPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])],
      repeatNewPassword: [null]
    });
    this.authorizationSettings.controls.newPassword.valueChanges.subscribe(data => {
      if (data) {
        data = data.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
      }
      this.authorizationSettings.controls.repeatNewPassword
        .clearValidators();
      this.authorizationSettings.controls.repeatNewPassword
        .setValidators(Validators.compose([Validators.required, Validators.pattern(data)]));
    });

我们需要先创建表单组,然后订阅第一个新密码字段,然后添加验证到重复字段

找到了更简单的解决方案。不确定这是否是正确的方法,但对我来说很有效

<!-- PASSWORD -->
<ion-item [ngClass]="{'has-error': !signupForm.controls.password.valid && signupForm.controls.password.dirty}">
    <ion-input formControlName="password" type="password" placeholder="{{ 'SIGNUP.PASSWORD' | translate }}" [(ngModel)]="registerCredentials.password"></ion-input>
</ion-item>

<!-- VERIFY PASSWORD -->
<ion-item [ngClass]="{'has-error': !signupForm.controls.verify.valid && signupForm.controls.verify.dirty}">
       <ion-input formControlName="verify" [(ngModel)]="registerCredentials.verify" type="password" pattern="{{registerCredentials.password}}" placeholder="{{ 'SIGNUP.VERIFY' | translate }}"> </ion-input>
</ion-item>

我已经为Angular 4实现了一个自定义密码匹配验证器

除了检查两个值是否匹配外,它还订阅来自其他控件的更改,并在两个控件中的任何一个更新时重新验证。您可以将其作为自己实现的参考,也可以直接复制

这里是解决方案的链接:


这里我提供了一份代码副本:

match-other-validator.ts
从'@angular/forms'导入{FormControl};
导出函数matchOtherValidator(otherControlName:string){
让这个控件:FormControl;
让其他控件:FormControl;
返回函数matchOtherValidate(控件:FormControl){
如果(!control.parent){
返回null;
}
//初始化验证器。
如果(!thisControl){
这个控制=控制;
otherControl=control.parent.get(otherControlName)作为FormControl;
如果(!其他控件){
抛出新错误('matchOtherValidator():在父组中找不到其他控件');
}
otherControl.valueChanges.subscribe(()=>{
thisControl.updateValueAndValidity();
});
}
如果(!其他控件){
返回null;
}
if(otherControl.value!==thisControl.value){
返回{
另一个:是的
};
}
返回null;
}
}
用法 以下是如何将其用于反应式表单:

private-constructForm(){
this.form=this.formBuilder.group({
电邮:[''[
需要验证器,
电子邮件
]],
密码:['',验证程序。必需],
重复密码:[''[
需要验证器,
matchOtherValidator(“密码”)
]]
});
}


更多最新的验证器可以在这里找到:。

好吧,我搜索了这个主题的答案,所有这些都太大了,不适合我的懒惰,所以我就这样做了。我认为这项工作做得很好

我使用ngModel绑定密码并重复密码输入,然后 显示或隐藏带有密码比较消息的div 角度2中的[隐藏]属性

密码
重复pasword
密码不匹配!

以下是我使用角度验证器的方法

组成部分:

import { UserModel } from '../../settings/users/user.model';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormRequestModel } from '../Shared/form.model';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-add-user',
  templateUrl: './add-user.component.html',
  styleUrls: ['./add-user.component.scss']
})
export class AddUserComponent implements OnInit {

  passwordsForm: FormGroup;
  user: UserModel;
  constructor(private fb: FormBuilder) { }

  ngOnInit() {

      this.passwordsForm = this.fb.group({
        inputPassword: ['', Validators.compose([Validators.required, Validators.minLength(6), Validators.maxLength(50)])],
        inputPasswordAgain: ['']
      });

  }
}
HTML:



密码 密码必须至少包含6个字符!!
   <label for="usr">Password</label>
   <input placeholder="12345" id="password" type="text" class="form-control" 
   [(ngModel)]="password">
   <label for="usr">Repeat pasword</label> 
   <input placeholder="12345" type="text" class="form-control" 
   [(ngModel)]="repeatPassword">
   <div [hidden]="password == repeatPassword">Passwords do not match!</div>
import { UserModel } from '../../settings/users/user.model';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormRequestModel } from '../Shared/form.model';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-add-user',
  templateUrl: './add-user.component.html',
  styleUrls: ['./add-user.component.scss']
})
export class AddUserComponent implements OnInit {

  passwordsForm: FormGroup;
  user: UserModel;
  constructor(private fb: FormBuilder) { }

  ngOnInit() {

      this.passwordsForm = this.fb.group({
        inputPassword: ['', Validators.compose([Validators.required, Validators.minLength(6), Validators.maxLength(50)])],
        inputPasswordAgain: ['']
      });

  }
}
 <form class="form-horizontal" [formGroup]="passwordsForm" novalidate>
   <div class="form-group">
    <br/>
    <label for="inputPassword" class="col-sm-2 control-label">Password</label>
    <div class="col-sm-10">
      <input type="password" formControlName="inputPassword" class="form-control" id="inputPassword" placeholder="Password">
    </div>
  </div>
   <div class="alert alert-danger" *ngIf="!passwordsForm.controls['inputPassword'].valid && passwordsForm.controls['inputPassword'].touched">Password must contain at least 6 characters!!</div>


  <div class="form-group">
    <br/>
    <label for="inputPasswordAgain" class="col-sm-2 control-label">Password again</label>
    <div class="col-sm-10">
      <input type="password" formControlName="inputPasswordAgain" class="form-control" id="inputPasswordAgain" placeholder="Password again">
    </div>
  </div>

  <!-- Show div warning element if both inputs does not match the validation rules below -->

   <div class="alert alert-danger" *ngIf="passwordsForm.controls['inputPasswordAgain'].touched
   && passwordsForm.controls['inputPasswordAgain'].value !== passwordsForm.controls['inputPassword'].value">
   Both passwords must be equal!</div>
import {AbstractControl} from '@angular/forms';

export class PasswordValidation {

    static MatchPassword(AC: AbstractControl) {
       const formGroup = AC.parent;
       if (formGroup) {
            const passwordControl = formGroup.get('Password'); // to get value in input tag
            const confirmPasswordControl = formGroup.get('Confirm'); // to get value in input tag

            if (passwordControl && confirmPasswordControl) {
                const password = passwordControl.value;
                const confirmPassword = confirmPasswordControl.value;
                if (password !== confirmPassword) { 
                    return { matchPassword: true };
                } else {
                    return null;
                }
            }
       }

       return null;
    }
}
this.registerForm = this.fb.group({ // <-- the parent FormGroup
                Email: ['', Validators.required ],
                Username: ['', Validators.required ],
                FirstName: ['', Validators.required ],
                Password: ['',
                                [
                                    Validators.required,
                                    Validators.minLength(6)
                                ]
                          ],
                Confirm: ['',
                                [
                                    Validators.required,
                                    PasswordValidation.MatchPassword
                                ]
                          ]
                });
<div [formGroup]="userFormPassword">
  <div>
    <input formControlName="current_password" type="password" placeholder="Current Password">
  </div>

  <div formGroupName="passwords">
    <input formControlName="new_password" type="password" placeholder="New Password">
  </div>

  <div formGroupName="passwords">
    <input formControlName="repeat_new_password" type="password" class="form-control" placeholder="Repeat New Password">
    <div class="input-error" *ngIf="
          userFormPassword.controls['passwords'].errors &&
          userFormPassword.controls['passwords'].errors.areEqual &&
          userFormPassword.controls['passwords'].controls.repeat_new_password.touched &&
          userFormPassword.controls['passwords'].controls.new_password.touched
        ">PASSWORDS do not match
    </div>
  </div>
</div>
export class HomeHeaderSettingsModalComponent implements OnInit {
  userFormPassword: FormGroup;
  // ...

  static areEqual(c: AbstractControl): ValidationErrors | null {
    const keys: string[] = Object.keys(c.value);
    for (const i in keys) {
      if (i !== '0' && c.value[ keys[ +i - 1 ] ] !== c.value[ keys[ i ] ]) {
        return { areEqual: true };
      }
    }
  }

  ngOnInit() {
    this.userFormPassword = new FormGroup({
      'current_password': new FormControl(this.user.current_password, [
        Validators.required,
      ]),
      'passwords': new FormGroup({
        'new_password': new FormControl(this.user.new_password, [
          Validators.required
        ]),
        'repeat_new_password': new FormControl(this.user.repeat_new_password, [
          Validators.required
        ])
      }, HomeHeaderSettingsModalComponent.areEqual)
    });
  }
}
import { AbstractControl, ValidatorFn } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';

export function matchOtherValidator(otherControlName: string): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } => {
        const otherControl: AbstractControl = control.root.get(otherControlName);

        if (otherControl) {
            const subscription: Subscription = otherControl
                .valueChanges
                .subscribe(() => {
                    control.updateValueAndValidity();
                    subscription.unsubscribe();
                });
        }

        return (otherControl && control.value !== otherControl.value) ? {match: true} : null;
    };
}
this.registerForm = formBuilder.group({
            email: ['', [
                Validators.required, Validators.email
            ]],
            password: ['', [
                Validators.required, Validators.minLength(8)
            ]],
            confirmPassword: ['', [
                Validators.required, matchOtherValidator('password')
            ]]
        });
form: FormGroup
passwordFieldName = 'password'
repeatedPasswordFieldName = 'repeatedPassword'

createForm() {
  this.form = this.formBuilder.group({
    login: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255), Validators.email]],
    [passwordFieldName]: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(255)]],
    [repeatedPasswordFieldName]: ['', [Validators.required, this.samePassword]]
  });

  this.form
    .get(passwordFieldName)
    .valueChanges.subscribe(() => {
      this.form
        .get(repeatedPasswordFieldName).updateValueAndValidity();
    })
}

samePassword(control: FormControl) {
  if (!control || !control.parent) {
    return null;
  }
  if (control.value !== control.parent.get(passwordFieldName).value) {
    return {'passwordMismatch': true}
  }
  return null;
}
<input type="password" class="form-control" formControlName="password">
<div class="alert alert-danger" *ngIf="!userForm.controls['password'].valid && userForm.controls['password'].touched">
    Enter valid password between 7 and 14 characters.
</div>
<input type="password" class="form-control" formControlName="confPassword">
<div *ngIf="userForm.controls['confPassword'].touched">
    <div class="alert alert-danger" *ngIf="userForm.controls['confPassword'].value != userForm.controls['password'].value">
        Password do not match
    </div>
</div>
'password':[null,  Validators.compose([Validators.required, Validators.minLength(7), Validators.maxLength(14))],
  'confPassword':[null, Validators.required]
import { Directive, Attribute  } from '@angular/core';
import { Validator,  NG_VALIDATORS } from '@angular/forms';

@Directive({
  selector: '[advs-compare]',
  providers: [{provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true}]
})
export class CompareDirective implements Validator {

  constructor(@Attribute('advs-compare') public comparer: string){}

  validate(c: Control): {[key: string]: any} {
    let e = c.root.get(this.comparer);
    if(e && c.value !== e.value){
      return {"compare": true};
    }
    return null;
  }
}
  static comparePassword(control) {  
    try {
      control.parent.value.password;
      if (control.parent.value.password == control.value) {
        return null;
      } else {
          return { 'invalidValue': true }; 
      }
   } catch (e) {
      e.message;
   }
 }