自定义比较密码验证器和此[Angular 2,4,5,6]

时间:2018-10-07 13:18:58

标签: angular angular2-forms angular2-directives

我尝试创建比较密码验证器

  comparePassword():{[s:string]:boolean}{
    console.log(this.formGroup);
    const password1 = this.formGroup.value.txtPassword1;
    const password2 = this.formGroup.value.txtPassword2;

    if(password1 === password2){

      return {passwordMismatch:true}
    }
    return null;
  }

,当我将其添加到formControl的验证器数组中时 我使用bind方法,以便它指向正确的上下文,但是它在运行时指向全局上下文,这在尝试访问时导致错误 this.formGroup.value.txtPassword1和this.formGroup.value.txtPassword2  因为this.formGroup是未定义的

import { Component, OnInit, EventEmitter } from '@angular/core';
import { NgbActiveModal, NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  constructor(private modalService: NgbModal) { 
    this.formGroup = new FormGroup({
      txtUserName: new FormControl('', Validators.required),
      txtPassword1: new FormControl('', Validators.required),
      txtPassword2: new FormControl('', [Validators.required, this.comparePassword.bind(this)])
    });
  }
  formGroup: FormGroup;
  ngOnInit() {

  }
  closeModal:EventEmitter<String>;

  closeResult: string;
  isLogin:boolean;


  open(content,option) {
    console.log(option);
    if (option) {

      this.isLogin = option === 'Login' ? true : false;
      console.log(this.isLogin);


    }
    this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' }).result.then((result) => {
     // this.closeResult = `Closed with: ${result}`;

    }, (reason) => {
      //this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;

    });
  }

  Submit(){
    console.log(this.formGroup);
   // this.formGroup.reset();
  }

  comparePassword():{[s:string]:boolean}{
    console.log(this.formGroup);
    const password1 = this.formGroup.value.txtPassword1;
    const password2 = this.formGroup.value.txtPassword2;

    if(password1 === password2){

      return {passwordMismatch:true}
    }
    return null;
  }


}

为什么即使使用bind方法后,它仍然指向全局上下文

我很难理解的事实是 当我从验证器内部控制台此值时,它具有formControl但附加了屏幕截图 enter image description here

但是当我解析所有对象的属性时,甚至列出了原型链中的属性,但没有列出formGroup

最奇怪的是,当我操作this时,实际上它里面有formGroup,但是如果我尝试使用this.formGroup来访问它,它会给我undefined

任何人都可以解释一下,我认为如果我能找到答案的话,那将是一种简单的方法,因为它有可能帮助很多人寻找简单的密码比较方法

2 个答案:

答案 0 :(得分:1)

预计自定义验证器将至少调用两次:

  1. 创建FormControl时(因此其状态在 与其初始值的关系)
  2. 创建FormControlName指令时(因此状态可以为 如果模板中定义了验证程序指令,则更新。)
    当它们在开始值中未被调用时,这就是为什么它未定义的原因

我建议您采取某种防范措施,并以以下方式提取FormControl

修改后的代码

   comparePassword(control: FormControl): { [key: string]: boolean } {
     if (control.parent){//
    const password1 = control.parent.value['password1'];
    const password2 = control.value;
      if(password1 === password2){
         return {passwordMismatch:true}
         }
     }
    return null;
  }

Live Demo

答案 1 :(得分:1)

似乎您绑定到this时, formGroup 尚未完全初始化(因此它是 undefined )。

如果将comparePassword验证移至 ngOnInit ,它将可以正常工作。

类似这样的东西:

  formGroup: FormGroup;
  constructor(private modalService: NgbModal) { 
    this.formGroup = new FormGroup({
      txtUserName: new FormControl('', Validators.required),
      txtPassword1: new FormControl('', Validators.required),
      txtPassword2: new FormControl('', Validators.required)
    });
  }

  ngOnInit() {
     this.formGroup.get('txtPassword2').setValidators(this.comparePassword.bind(this));
  }

Stackblitz example