2017-12-27 1067 views
0

请帮助理解。我正在尝试为被动表单编写自定义验证器。为什么表单值对象为空?

组件:

private form: FormGroup; 

    ngOnInit() { 
    const this_ = this; 

    this.form = new FormGroup({ 
     'email':  new FormControl(null, [Validators.required, Validators.email]), 
     'password': new FormControl(null, [Validators.required, Validators.minLength(6)]), 
     'password2': new FormControl(null, [Validators.required, Validators.minLength(6), this_.comparePasswords]), 
     'name':  new FormControl(null, [Validators.required]), 
     'agree':  new FormControl(false, [Validators.requiredTrue]) 
    }); 
    } 

    comparePasswords(c: FormControl) { 
    console.log(c); 

    const hashStr = Md5.hashStr(c.value.password); 
    const hashStr2 = Md5.hashStr(c.value.password2); 

    console.log(hashStr, hashStr2); 

    return (hashStr === hashStr2) ? null : { 
     comparePasswords: { 
     valid: false 
     } 
    }; 
    } 

所有你需要连接的进口。加载页面后,浏览器控制台立即显示表单对象,其中值对象为空。

我无法检查函数comparePasswords()。

控制台显示如下:

ERROR TypeError: Cannot read property 'password' of null

LIVE EXAMPLE HERE

+1

而是用空的默认密码值新formcontrol的,你为什么不设置默认值为空字符串'“”'?我敢打赌,这是问题。 –

+0

对不起,我没有看到@ I.R.R回答。评论 – Wallace

回答

3

变化null""

this.form = new FormGroup({ 
    'email':  new FormControl("", [Validators.required, Validators.email]), 
    'password': new FormControl("", [Validators.required, Validators.minLength(6)]), 
    'password2': new FormControl("", [Validators.required, Validators.minLength(6), this_.comparePasswords]), 
    'name':  new FormControl("", [Validators.required]), 
    'agree':  new FormControl(false, [Validators.requiredTrue]) 
}); 
+0

您是否使用OP的测试链接运行此代码并验证它解决了问题? – smac89

+0

@ smac89是的它适用于提供的示例 – Wallace

+0

这是适用于我的。 – Niladri

0

除了提供初始值null,您是在formcontrol设置自定义验证,所以你实际得到的自定义验证器只是formcontrol password2,不是整个formgroup。

因此,我会将自定义验证器放在formgroup级别,或者更好的是,为密码创建一个嵌套的formgroup并为其应用验证器。为什么?因为如果您在整个表单上应用验证器,则只要发生任何变化就会被触发。但在这个示例中,我将它应用于整个表单并缩小了您的代码。此外,在表单组级别上应用自定义验证程序(嵌套或不嵌套)的优势将兼顾检查输入。由于验证者坐在你的问题中,只会在password2字段发生更改时检查password2是否匹配password。那么如果在修改password2后修改password字段会发生什么情况,则不会显示错误,并且窗体被视为有效。

因此,建立形式,例如:

constructor(private fb: FormBuilder) { } 

ngOnInit() { 
    this.form = this.fb.group({ 
    password: ['', [Validators.required, Validators.minLength(6)]], 
    password2: ['', [Validators.required, Validators.minLength(6)]], 
    },{validator: this.comparePasswords}); 
} 

然后自定义验证应该是这样的:

comparePasswords(c: FormGroup) { 
    const hashStr = Md5.hashStr(c.controls.password.value); 
    const hashStr2 = Md5.hashStr(c.controls.password2.value); 
    return (hashStr === hashStr2) ? null : { notSame: true }; 
} 

你可以比较公正c.controls.password.valuec.controls.password2.value但因为使用的是Md5,我只是在这里使用了这些值。另外请注意,我们只是发送一个包含您选择的自定义错误的对象,如果密码不匹配,此处为notSame

,并显示错误信息,你可以这样做:

<div *ngIf="form.hasError('notSame')">Passwords do not match!</div> 

你修改StackBlitz