Angular 2表单验证重复密码

时间:2016-02-18 07:09:22

标签: angular

请参阅此question,了解验证器与angular2的比较字段。不幸的是Angular 2改变了一点,所以解决方案似乎不再起作用了。这是我的代码:

import {IonicApp,Page,NavController,NavParams} from 'ionic/ionic'
import {Component} from 'angular2/core'
import {FORM_PROVIDERS, FormBuilder, Validators} from 'angular2/common'
import {ControlMessages} from '../../components/control-messages'
import {ValidationService} from '../../services/validation-service'

@Page({
  templateUrl: 'build/pages/account/register.html',
  directives: [ControlMessages]
})
export class RegisterPage {

  constructor(nav:NavController,private builder: FormBuilder) {
    this.nav = nav
    this.registerForm = this.builder.group({
      'name' : ['', Validators.required],
      'email' : ['',Validators.compose([Validators.required, ValidationService.emailValidator])],
      'password' : ['',Validators.required],
      'repeat' : ['',this.customValidator]
      }
    )        
  }

  register() {    
    alert(this.registerForm.value.password)
  }

  private customValidator(control) {         
    //console.log(this.registerForm.value.password)
    //return {isEqual: control.value === this.registerForm.value.password}
    return true  
  }
}

我的HTML:

<ion-content class="account">
  <ion-list padding>
    <form [ngFormModel]='registerForm' (submit)='register()'>
      <div class="centered">
        <img class="logo" src="img/logo.png" alt="">
      </div>
      <div class="spacer" style="height: 20px;"></div>

      <ion-input>
        <ion-label floating>Name</ion-label>
        <input type="text" ngControl='name' id='name'>
        <control-messages control="name"></control-messages>            
      </ion-input>

      <ion-input>
        <ion-label floating>Email</ion-label>
        <input type="email" ngControl='email' id='email'>
        <control-messages control="email"></control-messages>               
      </ion-input>

      <ion-input>
        <ion-label floating>Password</ion-label>
        <input type="password" ngControl='password' id='password' value="">
        <control-messages control="password"></control-messages>        
      </ion-input>

      <ion-input>
        <ion-label floating>Confirm Password</ion-label>
        <input type="password" ngControl='repeat' id='repeat'>
        <control-messages control="repeat"></control-messages>                
      </ion-input>

      <button class="calm" full type='submit' [disabled]='!registerForm.valid'>Register</button>

      <ion-item style="background-color:transparent;border:none;">
        <button class="text-button" clear item-right (click)="gotoLogin()">Have an account already, Login</button>
      </ion-item>
    </form>
  </ion-list>

</ion-content>

但遗憾的是,我无法在验证功能中访问“密码”值。如果我取消注释 console.log(this.registerForm.value.password),则会收到以下错误消息:

  

EXCEPTION:TypeError:无法读取未定义

的属性'value'

有什么想法吗?感谢。

19 个答案:

答案 0 :(得分:69)

我在你的代码中看到了几个问题。您尝试在验证程序函数中使用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})
  });    
}

通过这种方式,您可以访问该群组的所有控件,而不仅仅是一个,并且不再需要使用this关键字...可以访问群组的表单控件使用FormGroup的controls属性。触发验证时提供FormGroup。例如:

matchValidator(group: FormGroup) {
  var valid = false;

  for (name in group.controls) {
    var val = group.controls[name].value
    (...)
  }

  if (valid) {
    return null;
  }

  return {
    mismatch: true
  };
}

有关详细信息,请参阅此anwer:

修改

要显示错误,您只需使用以下内容:

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

答案 1 :(得分:22)

我为Angular 4实现了自定义密码匹配验证器。

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

以下是解决方案的链接: https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30

在这里,我提供了代码的副本:

匹配另一validator.ts

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


export function matchOtherValidator (otherControlName: string) {

  let thisControl: FormControl;
  let otherControl: FormControl;

  return function matchOtherValidate (control: FormControl) {

    if (!control.parent) {
      return null;
    }

    // Initializing the validator.
    if (!thisControl) {
      thisControl = control;
      otherControl = control.parent.get(otherControlName) as FormControl;
      if (!otherControl) {
        throw new Error('matchOtherValidator(): other control is not found in parent group');
      }
      otherControl.valueChanges.subscribe(() => {
        thisControl.updateValueAndValidity();
      });
    }

    if (!otherControl) {
      return null;
    }

    if (otherControl.value !== thisControl.value) {
      return {
        matchOther: true
      };
    }

    return null;

  }

}

用法

以下是如何将其与反应形式一起使用:

private constructForm () {
  this.form = this.formBuilder.group({
    email: ['', [
      Validators.required,
      Validators.email
    ]],
    password: ['', Validators.required],
    repeatPassword: ['', [
      Validators.required,
      matchOtherValidator('password')
    ]]
  });
}

可以在此处找到更多最新的验证工具:moebius-mlm/ng-validators

答案 2 :(得分:12)

找到了更简单的解决方案。不确定这是否是正确的方法,但它适用于我

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

pattern="{{registerCredentials.password}}"

答案 3 :(得分:9)

Angular 4.3.3解决方案!

您可以使用以下内容执行此操作:html中的[formGroup]formGroupNameformControlName以及TS中的new FormGroupnew FormControl和自定义areEqual方法

<强> reg.component.html

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

<强> reg.component.ts

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

结果: result

答案 4 :(得分:4)

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

Angular 2 RC.5 form validation for password repeat

答案 5 :(得分:3)

通过使用此库ng2-validation-manager,您可以轻松完成此操作:

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

答案 6 :(得分:2)

此外,从具有形式0.2.0的角度2 rc4开始,需要标记和属性调出用于包含分组输入的组名称以防止错误

<div formGroupName="passwords">group input fields here... </div>

答案 7 :(得分:2)

将密码保存到实例变量中。

    password = new FormControl('', [Validators.required]);

然后在表单组中使用它。

        this.registrationForm = this.fb.group({
        'email': ['', [
            Validators.required,
            NGValidators.isEmail,
        ]
        ],
        'password': this.password,
        'password2': ['', [Validators.required, this.passwordMatch]]
    });

所以函数看起来像这样。

 private passwordMatch() {
        let that = this;
        return (c: FormControl) =>
        {
            return (c.value == that.password.value) ? null : {'passwordMatch': {valid: false}};
        }
    }

我知道这不是最好的解决方案,但它的工作正在进行中!

答案 8 :(得分:2)

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

  

我使用ngModel绑定密码和repeatPassword输入然后我   用密码比较消息显示或隐藏div   角度2中的[hidden]属性。

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

答案 9 :(得分:2)

我找到了一个解决方案,使我在代码的一致性和错误处理方面更加快乐:

1st:使用静态方法创建自定义验证类,该方法执行验证

此方法应该有一个AbstractControl参数,其中angular injects

请注意,您将在ConfirmPassword控件中传递此内容,因此您需要调用parent来获取FormGroup。从那里你可以调用formGroup.get('myControl')并获取密码控件,并在创建表单组时对其进行命名。

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

然后Angular会将'matchPassword':true添加到您的Confirm控件错误中,就像错过值时添加'required'一样真实

答案 10 :(得分:2)

我的Angular 4.3.4解决方案,不需要额外的FormGroup

  • repeatedPassword注册自定义验证程序,检查密码是否相同
  • 在表单创建期间password.valueChanges订阅处理程序,并在.updateValueAndValidity() method
  • 上致电repeatedPassword

以下是一些代码:

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

答案 11 :(得分:2)

<强>摘要

  • 每次其他控件的值发生更改时触发验证。
  • 取消订阅以避免内存泄漏
  • 返回{match: true}将允许我们使用myControl.hasError('match')
  • 检查给定控件是否出错

<强>实施

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

答案 12 :(得分:1)

这是我使用Angular Validators的方式

COMPONENT:

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:

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

答案 13 :(得分:1)

如果您想创建指令并使用它,那么see this

这是完整的指令代码

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

有关如何使用它的更多信息,请参阅http://www.advancesharp.com/blog/1226/angular-5-email-compare-password-validation-different-ways

答案 14 :(得分:1)

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

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

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

答案 15 :(得分:0)

刚开始使用Angular并且我找到了这个解决方案,不知道这是不是很好的做法:

  // Custom password confirmation validation
  static matchFieldValidator(fieldToMatch:string) : ValidatorFn {
    return (control : AbstractControl) : { [key: string]: any;} => {
      let confirmField = control.root.get(fieldToMatch);

      return (confirmField && control.value !== confirmField.value) ? {match:false} : null;
    }
  }

这样,您可以在设置验证规则时执行类似的操作

  this.registrationForm = fb.group({
    ...
    password1 : ['', [Validators.minLength(3)]],
    // remember to replace RegisterComponent with YOUR class name
    password2 : ['', [RegisterComponent.matchFieldValidator('password1')]], 
  });

答案 16 :(得分:0)

这是我遵循的最简单方法。我删除了不相关的代码。

我认为这会对你有帮助。

<强> auth.component.ts,auth.component.html,auth.component.css

&#13;
&#13;
import { Component, OnInit, EventEmitter, Input, Output ,Directive, forwardRef, Attribute,OnChanges, SimpleChanges} from '@angular/core';
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn  } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';

import { RegisterUser } from '../shared/models';

@Component({
  moduleId: module.id,
  selector: 'auth-page',
  styleUrls: ['./auth.component.css'],
  templateUrl: './auth.component.html'
})

export class AuthComponent implements OnInit {
  userRegisterModel: RegisterUser = new RegisterUser();
    
    constructor(private route: ActivatedRoute, private router: Router) {   }
  
  ngOnInit() { 
    this.userRegisterModel.LoginSource = 'M';//Manual,Facebook,Google
}

  userRegister() {
  console.log(this.userRegisterModel);
  }

}
&#13;
.validation
{
  margin:0;
  padding-top: 1px;
  padding-bottom: 0px;
}
.validation .message
{
    font-size: 10px;
    color: #de1a16;
}
&#13;
           <form (ngSubmit)="userRegister()" #authRegisterForm="ngForm" novalidate>

                            <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <label>First Name:</label>
                                <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.firstName" name="firstName"
                                    #firstName="ngModel" placeholder="Your first name">
                                <div style="display: flex;">&nbsp;
                                    <div [hidden]="firstName.valid || firstName.pristine" class="validation">
                                        <div [hidden]="!firstName.hasError('required')" class="message">Name is required</div>
                                        <div [hidden]="!firstName.hasError('pattern')" class="message">Only alphabets allowed</div>
                                    </div>
                                </div>
                            </div>

                            <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <label>Last Name:</label>

                                <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.lastName" name="lastName"
                                    #lastName="ngModel" placeholder="Your last name">


                                <div style="display: flex;">&nbsp;
                                    <div [hidden]="lastName.valid || lastName.pristine" class="validation">
                                        <div [hidden]="!lastName.hasError('required')" class="message">Name is required</div>
                                        <div [hidden]="!lastName.hasError('pattern')" class="message">Only alphabets allowed</div>
                                    </div>
                                </div>
                            </div>

                            <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <label>Email:</label>

                                <input type="text" class="form-control" required [(ngModel)]="userRegisterModel.email" name="email" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"
                                    #email="ngModel" placeholder="Your email">

                                <div style="display: flex;">&nbsp;
                                    <div [hidden]="email.valid || email.pristine" class="validation">
                                        <div [hidden]="!email.hasError('required')" class="message">Email is required</div>
                                        <div [hidden]="!email.hasError('pattern')" class="message">Email format should be
                                            <small>
                                                <b>john@doe.com</b>
                                            </small>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <label>Password:</label>
                                <input type="password" class="form-control" required [(ngModel)]="userRegisterModel.password" name="password" #password="ngModel"
                                    minlength="6" placeholder="Your strong password" >

                                <div style="display: flex;">&nbsp;
                                    <div [hidden]="password.valid || password.pristine" class="validation">
                                        <div [hidden]="!password.hasError('minlength')" class="message">Password should be 6digit</div>
                                        <div [hidden]="!password.hasError('required')" class="message">Password is required</div>
                                    </div>
                                </div>
                            </div>

                            <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <label>Confirm Password:</label>
                                <input type="password" class="form-control" required validateEqual="password" [(ngModel)]="userRegisterModel.confirmPassword"
                                    name="confirmPassword" #confirmPassword="ngModel" placeholder="Confirm your password">

                                <div style="display: flex;">&nbsp;
                                    <div [hidden]="confirmPassword.valid || confirmPassword.pristine" class="validation">
                                        <div class="message">Passwords did not match</div>
                                    </div>
                                </div>
                            </div>

               
                            

                            <div class="col-md-12 form-group text-right" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;">
                                <button type="submit" class="btn btn-primary" [disabled]="!authRegisterForm.form.valid">
                                    Submit form
                                    <i class="icon-arrow-right14 position-right"></i>
                                </button>
                            </div>
                        </form>
&#13;
&#13;
&#13;

<强> registerUser.mocel.ts

&#13;
&#13;
export class RegisterUser {
    FirstName : number;
    LastName : string;
    Email: string;
    Password : string;  
  }      
&#13;
&#13;
&#13;

<强> password.match.directive.ts

&#13;
&#13;
import { Directive, forwardRef, Attribute } from '@angular/core';
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from '@angular/forms';

@Directive({
    selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
    providers: [
        { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
    ]
})
export class EqualValidator implements Validator {
    constructor( @Attribute('validateEqual') public validateEqual: string) {}

    validate(c: AbstractControl): { [key: string]: any } {
        // self value (e.g. retype password)
        let v = c.value;

        // control value (e.g. password)
        let e = c.root.get(this.validateEqual);

        // value not equal
        if (e && v !== e.value) return {
            validateEqual: false
        }
        return null;
    }
}
&#13;
&#13;
&#13;

<强> app.module.ts

&#13;
&#13;
import { ModuleWithProviders, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';

//import { AppRoutingModule } from './app-routing.module';
//import { AppComponent } from './app.component';

//shared components
import {  EqualValidator} from './shared/password.match.directive';

@NgModule({
  declarations: [
   // AppComponent,
    //FooterComponent,
   // HeaderComponent,
   // LoginComponent,
   // LayoutComponent,
   // AuthComponent,
   // UserExistComponent,
  //  HomeComponent,
    EqualValidator
  ],
  imports: [
  // BrowserModule,    
  //  AppRoutingModule,
  //  SharedModule   
  ],
  providers: [
   // ApiService,
   // AuthGuard,
    //JwtService,  
   // UserService,
   // HomeAuthResolver,
   // NoAuthGuard,
   // SharedService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
&#13;
&#13;
&#13;

答案 17 :(得分:0)

我认为我们不需要自定义验证器来匹配密码,这可以通过formname.controls['controlName'].value轻松实现。

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

fileName.component.ts表单控件中声明为:

'password':[null,  Validators.compose([Validators.required, Validators.minLength(7), Validators.maxLength(14))],
  'confPassword':[null, Validators.required]

答案 18 :(得分:0)

回应周浩提出辩论问题的人我认为这就是你所寻找的,因为它发生在我身上和你一样,他说这个变量是未定义的并且像这样解决:

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