我试图在角度基础上对基于模型的表单进行异步验证。为简单起见,我删除了表单的所有其他字段。在实际示例中,还有更多字段。
public_data
buildForm(): void {
this.registerForm = this.fb.group({
'username':
[this.user.username, [Validators.required, Validators.minLength(4)],
[this.validateUsernameUnique.bind(this)]]
});
this.registerForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged(); // set validation messages now
}
方法应调用服务并远程检查用户名是否已存在并返回true或false。该服务正常运行,其结果按预期显示在控制台上。
validateUsernameUnique()
我尝试跳过此验证,直到值为> = 4,因为我希望validateUsernameUnique(control: AbstractControl) {
clearTimeout(this.usernameCheckTimeout);
return new Promise((resolve) => {
this.usernameCheckTimeout = setTimeout(() => {
if (control.value.length >= 4) {
this.userService.doesUsernameExist(control.value)
.then(res => {
if (!res) {
resolve(null);
} else {
resolve({nameTaken: true});
}
});
} else {
resolve(null);
}
}, 1000);
});
}
- 验证在此之前显示。
验证消息的定义如下:
minLength(4)
minLength() - 检查按预期在开头工作,formErrors = {
'username': ''
};
validationMessages = {
'username': {
'required': 'username is required',
'minlength': 'username must be at least 4 characters long',
'nameTaken': 'username does already exist'
}
};
也显示在表单上。但当我达到4个字符时,我在控制台中出现异常:
username must be at least 4 characters long
发生错误后,不再显示验证消息,minLength-Validation也不再有效。
stackTrack报告TypeError: can't convert null to object
Stack trace:
UserRegisterComponent.prototype.onValueChanged@webpack-internal:///./src/app/user/user-register/user-register.component.ts:111:39
UserRegisterComponent.prototype.buildForm/<@webpack-internal:///./src/app/user/user-register/user-register.component.ts:63:49
中的问题,此方法如下所示:
onValueChanged():111
如何让同步和异步验证并行工作?我在同一个组件中使用async-Validation-Method获取方法,该方法也来自SO。
如何让onValueChanged(data?: any) {
if (!this.registerForm) {
return;
}
const form = this.registerForm;
for (const field of Object.keys(this.formErrors)) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key of Object.keys(control.errors)) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
- errorMessage出现在表单上?验证中的nameTaken
承诺是错误的方法吗?
任何意见都表示赞赏。不知道我究竟如何调试电流行为以了解问题所在。
答案 0 :(得分:1)
validateUsernameUnique()
似乎也出现了错误。您键入return this.userService.doesUsernameExist(control.value).then()...
,它将在请求完成之前返回函数。
在return
之前尝试不使用this.userService.doesUsernameExist(...)
。
如果你仍然收到错误,我猜这是因为尝试在null上调用Object.keys()
。在执行control.errors
Object.keys(control.errors)
的值是多少