我正在尝试创建自定义表单验证器,但我不断收到此错误。无法读取null的属性“值”。几天来,我一直在努力解决问题,这是我的FormGroup:
this.step1Form = this.fb.group({
username: new FormControl('', {
validators: [Validators.required,
Validators.minLength(4),
this.checkUsername.bind(this)],
}),
email: new FormControl('', {
validators: [Validators.required,
Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
}),
password: new FormControl('', {
validators: [Validators.required,
Validators.minLength(8)],
}),
repeat: new FormControl('', {
validators: [Validators.required,
Validators.minLength(8)],
}),
});
这是我的checkUsername方法
checkUsername(g: FormGroup) {
return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {
return typeof data["error"] != 'undefined' ? null : {'taken': true};
}));
}
这是this.dataService中的checkUsername方法
checkUsername(username):Observable<any> {
return this.http.get(globals.baseUrl+'/user/' + username, {headers:this.utilService.getHeadersJson()}).map(this.utilService.map);
}
我得到了错误:
无法读取null的属性“值”
在此行
return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {
我在做什么错?我试过没有这样的管道
checkUsername(g: FormGroup) {
return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
return typeof data["error"] != 'undefined' ? null : {'taken': true};
});
}
但是那没有用,我还在不同的位置尝试过验证器,例如:
this.step1Form = this.fb.group({
username: new FormControl('', {
validators: [Validators.required,
Validators.minLength(4)],
}),
email: new FormControl('', {
validators: [Validators.required,
Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
}),
password: new FormControl('', {
validators: [Validators.required,
Validators.minLength(8)],
}),
repeat: new FormControl('', {
validators: [Validators.required,
Validators.minLength(8)],
}),
}, { validator: this.checkUsername.bind(this)});
也没用。
请帮助!
我也尝试过这个:
username: new FormControl('', {
validators: [Validators.required,
Validators.minLength(4)],
asyncValidator: [this.checkUsername.bind(this)],
}),
遇到此错误:
类型'{验证符:ValidatorFn []; asyncValidator:any []; }'不能分配给'ValidatorFn |类型的参数。 AbstractControlOptions | ValidatorFn []'。对象文字只能 指定已知属性,并且'asyncValidator'在类型中不存在 'ValidatorFn | AbstractControlOptions | ValidatorFn []'。
答案 0 :(得分:0)
角反应形式立即并经常调用验证器。在框架中实例化每个子控件时,表单组中的跨字段验证器将开始进行验证。
为防止其引发过早的验证错误,您可能需要确保已将相关控件实例化,如下所示:
checkUsername(g: FormGroup) {
if (!g || !g.get('username')) {
return null;
}
return this.dataService.checkUsername(g.get('username').value).subscribe(data => {
return typeof data["error"] != 'undefined' ? null : {'taken': true};
});
}
您的第二次尝试似乎是一个更好的方向,因为它是'username'控件的异步验证器,但是asyncValidators属性中有一个错字(缺少's')。如果您未在函数中引用“ this”,则也可能不需要.bind(this)。
username: new FormControl('', {
validators: [Validators.required, Validators.minLength(4)],
asyncValidators: [this.checkUsername]
})
然后,您的验证程序仅处理单个表单控件而不是整个组,就像这样:
checkUsername(c: FormControl) {
if (!c) { return null; }
return this.dataService.checkUsername(c.value).subscribe(data => {
return typeof data["error"] != 'undefined' ? null : {'taken': true};
});
}