【问题标题】:Generic email validator通用电子邮件验证器
【发布时间】:2016-03-08 10:14:37
【问题描述】:

我想创建一个表单,用户将在其中输入他的电子邮件。我想在客户端验证电子邮件格式。

Angular 2 中是否有任何通用的电子邮件验证器?

注意:类似于AngularJS validator

【问题讨论】:

    标签: angular typescript angular2-forms


    【解决方案1】:

    您可以在没有表单的情况下使用内置的 Angular 表单验证器。我不确定这是否是好的做法,但它确实有效。

    const control = new FormControl('', Validators.email);
    control.setValue(valueToCheck);
    console.log(control.errors);
    

    其他答案已经展示了如何在表单中使用它:

    this.contactUsForm = this.formBuilder.group({
          firstName: new FormControl('', Validators.required),
          lastName: new FormControl('', Validators.required),          
          emailAddress: new FormControl('', [Validators.required, Validators.email]),
          message: new FormControl('', Validators.required)
        });
    

    【讨论】:

      【解决方案2】:

      这是使用 RegEx 验证字段的另一种方法。您可以将方法绑定到字段的 keyUp 事件。

      在您的组件中:

      import {NgForm} from 'angular2/common';
      
      //...
      
      emailValidator(email:string): boolean {
          var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      
          if (!EMAIL_REGEXP.test(email)) {
              return false;
          }
          return true; 
      }
      

      在您的 HTML(视图)中

      <div class="form-group">
          <label>Email address</label>
          <input type="email" class="form-control" [(ngModel)]="user.email"
                 placeholder="Email address" required ngControl="email"
                 #email="ngForm"
                 (keyup)="emailValidator(email.value) == false ? emailValid = false : emailValid = true">
          <div [hidden]="emailValid || email.pristine" class="alert alert-sm alert-danger">Email address is invalid</div>
      </div>
      

      另一个选项(必填字段 + 用户离开字段时验证)

      <div class="form-group">
          <label for="registerEmail">Email address</label>
          <input type="email" class="form-control" [(ngModel)]="user.email"
                 placeholder="Email address" required ngControl="email"
                 #email="ngForm"
                 (blur)="emailValidator(email.value) == true ? emailIsInvalid = false : emailIsInvalid = true">
          <div [hidden]="email.valid || email.pristine" class="alert alert-sm alert-danger">This field is required</div>
          <div [hidden]="!emailIsInvalid" class="alert alert-sm alert-danger">Email address is invalid</div>
      </div>
      

      此方法适用于任何验证,因此您可以更改正则表达式并验证信用卡、日期、时间等...

      【讨论】:

        【解决方案3】:

        Angular 4 更新

        ngOnInit() {
            this.user = new FormGroup({
                name: new FormGroup({
                    firstName: new FormControl('',Validators.required),
                    lastName: new FormControl('')
                }),
                age: new FormControl('',null,validate),
                email: new FormControl('',emailValidator),
            // ...
            });
        }
        

        验证器

        export function emailValidator(control: AbstractControl):{[key: string]: boolean} {
            var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
            if (control.value != "" && (control.value.length <= 5 || !EMAIL_REGEXP.test(control.value))) {
                return {invalid:true};
            }
            return null;
        }
        

        模板

        <div class="row">
            <div class="col-md-12">
                <md-input-container>
                    <input mdInput type="text" placeholder="Email" formControlName="email">
                </md-input-container>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <span *ngIf="user.get('email').touched && !user.get('email').valid && !user.get('email').pristine">
                    <small>Invalid email</small>
                </span>
            </div>
        </div>
        

        【讨论】:

          【解决方案4】:

          您可以使用表单指令和控件来执行此操作。

          export class TestComponent implements OnInit {
               myForm: ControlGroup;
               mailAddress: Control;
          
               constructor(private builder: FormBuilder) {
                   this.mailAddress = new Control(
                      "",
                      Validators.compose([Validators.required, GlobalValidator.mailFormat])
                  );
               }
          
               this.addPostForm = builder.group({
                      mailAddress: this.mailAddress
               });
          }
          

          进口:

          import { FormBuilder, Validators, Control, ControlGroup, FORM_DIRECTIVES } from 'angular2/common';
          

          然后你的GlobalValidator 班级:

          export class GlobalValidator {
          
              static mailFormat(control: Control): ValidationResult {
          
                  var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
          
                  if (control.value != "" && (control.value.length <= 5 || !EMAIL_REGEXP.test(control.value))) {
                      return { "incorrectMailFormat": true };
                  }
          
                  return null;
              }  
          }
          
          interface ValidationResult {
              [key: string]: boolean;
          }
          

          然后是你的 HTML:

          <div class="form-group">
              <label for="mailAddress" class="req">Email</label>
              <input type="text" ngControl="mailAddress" />
              <div *ngIf="mailAddress.dirty && !mailAddress.valid" class="alert alert-danger">
                  <p *ngIf="mailAddress.errors.required">mailAddressis required.</p>
                  <p *ngIf="mailAddress.errors.incorrectMailFormat">Email format is invalid.</p>
              </div>
          </div>
          

          有关这方面的更多信息,您可以阅读这篇好文章:https://medium.com/@daviddentoom/angular-2-form-validation-9b26f73fcb81#.jrdhqsnpg 或查看此 github 项目以获取 working example

          (编辑:reg ex 似乎没有检查域中的点

          我用这个代替

          /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
          

          cfrhttp://emailregex.com/

          【讨论】:

          • 其中一个限制是 Angular2 仍然不允许异步验证器中的 http 请求。这个问题仍然在 github 上打开:github.com/angular/angular/issues/1068#issuecomment-183766054
          • 注意!!!这里正则表达式 EMAIL_REGEXP 构造不正确,它显示此邮件有效:“asd@f”
          • @JustShadow 从技术上讲,电子邮件地址是有效的。然而,对 5 个以上字符的限制与此正则表达式不一致。
          • 在 Angular 2.4.1 中用于控制的是什么?
          • 如果我不关心xxx@gmail.com 无效,我可以将email 添加到我的输入中
          【解决方案5】:

          您只能使用 html:

          <md-input-container class="md-icon-float md-block" flex-gt-sm>
              <label>Email</label>
                  <input md-input
                      id="contact-email"
                      type="text"
                      ngControl="email"
                      #email="ngForm"
                      [(ngModel)]="contact.email"
                      required
                      pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,6})+$">
          
              <div class="md-errors-spacer" [hidden]="email.valid || email.untouched">
                  <div class="md-char-counter" *ngIf="email.errors && email.errors.required">
                      Email is required
                  </div>
                  <div class="md-char-counter" *ngIf="email.errors && email.errors.pattern">
                      Email is invalid
                  </div>
              </div>
          </md-input-container>
          

          【讨论】:

          • 比起使用基于代码的解决方案,我更喜欢这种方法...谢谢!
          • FWIW,使用新的域名后缀,如 .google、.bike。和许多其他的电子邮件验证模式需要调整。这可能会有所帮助:emailregex.com 对于 HTML5 中的 JavaScript,这是模式:pattern="^[a-zA-Z0-9.!#$%&amp;’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"
          • 对我有用的模式是:pattern="^(\\w|[0-9.!#$%&'*+/=?^_\`{|}~- ])+@(\\w|[0-9-])+(?:[.](\\w|[0-9-])+)*$" 注意双反斜杠。该模式无法在每个“w”之前仅使用一个反斜杠。原因可能是这个字符串存在于@Component 的模式属性中。不过不确定。
          • 尝试为电子邮件编写符合 RFC 的正则表达式可能会非常复杂。多年来,人们一直在争论这个问题。我建议最好的正则表达式是在 @ 符号之前检查一些东西,然后在它之后用一个点检查一些东西。然后通过向该地址发送电子邮件验证来跟进。这看起来像:pattern=".+@.+\..+"
          • 我的浏览器在输入长电子邮件时冻结,使用这种方法。问题可能出在正则表达式本身。
          【解决方案6】:

          我正在使用: https://www.npmjs.com/package/ng2-validation

          npm install ng2-validation --save ng2-validation

          我没有回答您的问题,但对于很多常见场景,您可以找到已经实现的自定义验证器

          你的例子: 电子邮件:['',[CustomValidators.email]]

          致以最诚挚的问候,

          【讨论】:

            【解决方案7】:

            对于 Angular 4 及以上:

            根据This,您可以使用“电子邮件验证器”。

            例子:

            如果您使用模板驱动的表单:

            <input type="email" name="email" email>
            <input type="email" name="email" email="true">
            <input type="email" name="email" [email]="true">
            

            如果您使用模型驱动表单(又名 ReactiveFormsModule),请使用 Validators.email

            this.myForm = this.fb.group({
                firstName: ['', [<any>Validators.required]],
                email: ['', [<any>Validators.required, <any>Validators.email]],
            });
            

            旧答案:您可以使用 angular 2 FormGroup

            通过像这样使用 validators.pattern 和正则表达式:

             let emailRegex = '^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$';
             this.myForm = this.fb.group({
                    firstName: ['', [<any>Validators.required]],
                    email: ['', [<any>Validators.required,  <any>Validators.pattern(emailRegex) ]],
             });
            

            【讨论】:

            • 不起作用,总是返回 false(但当我运行 pattern.test('xxx') 时实际上是 true)
            • @Daniel.Woo 也许您可以更改电子邮件正则表达式来解决这个问题?
            • 这在我看来是最好的答案。使用 Validators.pattern 是最好的方法。正则表达式似乎也很完美。我在这里尝试了所有的正则表达式:stackoverflow.com/questions/46155/…,但它们并不适合我。只是这个答案中的正则表达式对我有用。
            • 这是最简单的电子邮件验证方法。您可以将 Validators.pattern(regexp) 包装在方法调用中,然后最终得到一个自定义验证器。每次都重新发明轮子是没有意义的。
            • 允许,如果我输入此格式ram.ram@ra。这意味着它将在电子邮件 ID 上不带点 (.) 的情况下被接受。
            【解决方案8】:

            您还可以将ng2-validation-manager 用于响应式表单,这使得验证匹配更容易:

            this.form = new ValidationManager({
              'email'       : 'required|email',
              'password'    : 'required|rangeLength:8,50'
            });
            

            和视图:

            <form [formGroup]="form.getForm()" (ngSubmit)="save()">
            
                <div class="form-group">
                  <label>Email</label>
                  <input type="text" class="form-control" formControlName="email">
                  <div *ngIf="form.hasError('email')" class="alert alert-danger">
                    {{form.getError('email')}}
                  </div>
                </div>
            
                <div class="form-group">
                  <label>Password</label>
                  <input type="password" class="form-control" formControlName="password">
                  <div *ngIf="form.hasError('password')" class="alert alert-danger">
                    {{form.getError('password')}}
                  </div>
                </div>
                <button type="submit" class="btn btn-success">Submit</button>
            </form>
            

            【讨论】:

              【解决方案9】:

              我认为现在你可以在这里使用浏览器验证。电子邮件字段有不错的支持,您可以从element.validity.valid 获得验证结果。你只需要通过 Angular 自定义验证器来传递它

              详情请参阅https://developer.mozilla.org/en-US/docs/Web/API/ValidityStatehttp://caniuse.com/#feat=input-email-tel-url

              【讨论】:

              • 您能举个例子详细说明一下吗?此外,这仅适用于 Web 应用程序。
              【解决方案10】:

              另一种方法是使用自定义指令。我喜欢这种方法,因为它与其他 ng2 验证器更加一致。

              import { Directive, forwardRef } from '@angular/core';
              import { NG_VALIDATORS } from '@angular/forms';
              import { Validator, AbstractControl } from '@angular/forms';
              
              
              @Directive({
                  selector: '[validateEmail][formControlName], [validateEmail][formControl],[validateEmail][ngModel]',
                  providers: [
                      { provide: NG_VALIDATORS, useExisting: forwardRef(() => EmailValidator), multi: true }
                  ]
              })
              export class EmailValidator implements Validator {
              
                  constructor() {
                  }
              
                  validate(c: AbstractControl) {
                      let EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
              
                      return EMAIL_REGEXP.test(c.value) ? null : {
                          validateEmail: {
                              valid: false
                          }
                      };
              
              
                  }}
              

              那么在html中的用法就是

              <input class="form-control" 
                             type="email"
                             [(ngModel)]="user.emailAddress" 
                             name="emailAddress" 
                             placeholder="first.last@example.com"
                             validateEmail
              

              【讨论】:

              • 允许,如果我输入此格式ram.ram@ra。这意味着它将在电子邮件 ID 上不带点 (.) 的情况下被接受。
              • 类似于blog.thoughtram.io/angular/2016/03/14/…,因为任何人都在搜索完整的代码示例……这个很好,因为它内联在 html 标记中
              【解决方案11】:

              我想刚才没有电子邮件验证器,但添加自定义验证器很容易。看到这个demo 我使用了与 angular1 相同的正则表达式。

              function emailValidator(control) {
                var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
              
                if (!EMAIL_REGEXP.test(control.value)) {
                  return {invalidEmail: true};
                }
              }

              【讨论】:

              • 注意!!!这里正则表达式 EMAIL_REGEXP 构造不正确,它显示此邮件有效:“asd@f”
              • 事实上,asd@f 是遵循 RFC 821 (tools.ietf.org/html/rfc821) 的有效电子邮件地址
              猜你喜欢
              • 1970-01-01
              • 2020-04-10
              • 2018-10-23
              • 2017-10-12
              • 1970-01-01
              • 2018-08-15
              • 2023-03-26
              • 2022-10-20
              • 2011-03-21
              相关资源
              最近更新 更多