我的目标是将所有验证消息放在组件中而不是 html 文件中
我有一个注册页面,下面是字段:
public buildRegisterForm() {
this.userForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(3)]],
lastName: ['', [Validators.required, Validators.maxLength(50)]],
emailGroup: this.fb.group({
email: ['', [Validators.required, Validators.pattern(this.emailPattern)]],
retypeEmail: ['', Validators.required],
}, { validator: formMatcherValidator('email', 'retypeEmail') }),
passwordGroup: this.fb.group({
password: ['', [Validators.required, strongPasswordValidator()]],
retypePassword: ['', Validators.required],
}, { validator: formMatcherValidator('password', 'retypePassword')}),
});
}
我正在学习本教程 link实现我想要的是
将我所有的验证消息放在组件文件而不是 html 文件中。
export const validationMessages = {
'firstName': {
'required': 'Your first name is required.',
'minlength': 'Your first name must be at least 3 characters long.'
},
'lastName': {
'required': 'Your last name is required.',
'minlength': 'Your last name must be less than 50 characters long.'
},
'emailGroup': {
'email': {
'required': 'Your email is required',
'pattern': 'Your login email does not seem to be a valid email address.'
},
'retypeEmail': {
'required': 'Your retype email is required',
'match': 'The email provided do not match.'
},
},
'passwordGroup':{
'password': {
'required': 'Your password is required',
'strongPassword': 'Your password must be between 8 - 15 characters and must contain at least three of the following: upper case letter, lower case letter, number, symbol.'
},
'retypePassword': {
'required': 'Your retype password is required',
'match': 'The password provided do not match.'
}
}
onValueChanged 方法
private onValueChanged(data?: any) {
if (!this.userForm) { return; }
const form = this.userForm;
// tslint:disable-next-line:forin
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
let control = form.get(field);
// console.log("control", control.dirty);
console.log("controlEmail", control);
if (control && (control.dirty || control.touched) && control.invalid) {
let messages = validationMessages[field];
// tslint:disable-next-line:forin
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
当我有多个 formBuider 组或嵌套对象时,此方法不起作用。这 1 有什么建议吗?
类似于此 How to validate reactive forms with nested form groups?
最佳答案
在我看来,您需要在 onValueChanged(data)
方法中创建一个嵌套循环。由于您有很多嵌套组,因此我不会复制它。但是嵌套循环是通用的,因此它适用于您的所有组。但这是一个只有一个嵌套组而不是多个嵌套组的示例。我正在使用英雄示例。
嵌套的组名是group
,里面的formcontrol叫做child
。
formErrors
应该在 group
中包含 child
:
formErrors = {
'name': '',
'power': '',
'group':{
'child': ''
}
};
所以一定要记住,在模板中添加验证时,需要使用:
<div *ngIf="formErrors.group.child">
{{ formErrors.group.child }}
</div>
验证消息不会在 group
中,但就像其他验证消息一样:
validationMessages = {
'name': {
'required': 'Name is required.',
},
'power': {
'required': 'Power is required.'
},
'child': {
'required': 'Child is required.',
}
};
最后,修改后的onValueChanges
:
onValueChanged(data?: any) {
if (!this.heroForm) { return; }
const form = this.heroForm;
// iterate toplevel of formErrors
for (const field in this.formErrors) {
// check if the field corresponds a formgroup (controls is present)
if(form.get(field).controls ) {
// if yes, iterate the inner formfields
for(const subfield in form.get(field).controls) {
// in this example corresponds = "child", reset the error messages
this.formErrors[field][subfield] = '';
// now access the actual formfield
const control = form.get(field).controls[subfield];
// validate and show appropriate error message
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[subfield];
for (const key in control.errors) {
this.formErrors[field][subfield] += messages[key] + ' ';
}
}
}
}
// does not contain a nested formgroup, so just iterate like before making changes to this method
else {
const control = form.get(field);
this.formErrors[field] = '';
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
}
最后,一个DEMO :)
Plunker
你必须记住,尽管在你的情况下这是有效的,但如果嵌套组中有嵌套组,这将不起作用,那么你必须在 onValueChanges 中进行另一个循环
,但你在这里没有那个问题;)
关于Angular 2 - 响应式(Reactive)表单验证消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43383341/