Angular 2-反应形式验证消息 [英] Angular 2 - Reactive form Validation messages

查看:41
本文介绍了Angular 2-反应形式验证消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个注册页面,下面是字段:

I have a sign up page and below is the fields:

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')}),
});
}

我正在按照本教程链接实现我想要的是 将我所有的验证消息放在组件文件中,而不是html文件中.

I'm following this tutorial link to achieve what I want which is to put all my validation messages in component file instead of html file.

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方法


onValueChanged method

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有什么秘诀吗?
类似于此如何使用嵌套验证反应式表单组?

And this method is not working when I have multi formBuider Group or nested Object. Any tips for this 1?
similar to this How to validate reactive forms with nested form groups?

推荐答案

按照我的看法,您需要在onValueChanged(data)方法内部创建一个嵌套循环.由于您有很多嵌套的组,因此我不再重复.但是嵌套循环是通用的,因此它适用于所有组.但是,这是一个只有一个嵌套组而不是多个嵌套组的示例.我以英雄为例.

The way I see it, you need to create a nested loop inside the onValueChanged(data)-method. Since you have pretty many nested groups, I'm not going to replicate that. But the nested loop is generic, so it works for all your groups. But here is an example with just one nested group instead of several. I'm using the heroes example.

嵌套的组名称为group,其内部的窗体控件称为child.

The nested group name is group, and the formcontrol inside that is called child.

formErrors应该在内部group中包含child:

formErrors = {
  'name': '',
  'power': '',
  'group':{
    'child': ''
  }
};

因此,您必须记住在模板中添加验证时,需要使用:

Therefore you must remember when you add the validation in the template, you need to use:

<div *ngIf="formErrors.group.child">
   {{ formErrors.group.child }}
</div>

验证消息不会出现在group内部,但与其他验证消息一样:

Validation messages won't be inside group, but just like the other validation messages:

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] + ' ';
        }
      } 
    }
  }
}

最后是一个演示:)

您必须记住,虽然在您的情况下这可行,但是如果嵌套组中有嵌套组,则此方法不起作用,那么您必须在onValueChanges中进行另一个循环,但您这里没有这个问题;)

You'd have to remember though that in your case this works, but IF there would be nested groups inside the nested groups, this would not work, then you'd have to make yet another loop in the onValueChanges, but you don't have that problem here ;)

这篇关于Angular 2-反应形式验证消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆