首页 > 解决方案 > Angular 电子邮件验证组件/服务

问题描述

我有一个 Angular2 应用程序,我想利用系统中其他地方使用的现有电子邮件验证服务。这是一个 REST API,我只是将电子邮件发送给它,它会返回一个带有几个值的对象,其中一个是 boolean valid。我还想让它在同一个表单中可重复使用和多次使用,例如同一个表单中的两个电子邮件字段。

首先,我创建了一个服务,该服务具有一个validateEmail执行实际GET调用的方法,并将响应映射json到一个UserEmailVerification对象。

然后我做了一个EmailComponent服务imports,并有一个去抖动的方法来调用它。

import {Component, Input, OnInit} from '@angular/core';
import {UserEmailVerification} from "../../model/email/email-verification.model";
import {ValidateEmailService} from "../../services/validate-email.service";
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Component({
  selector: 'app-email',
  templateUrl: 'email.component.html',
  styleUrls: ['email.component.scss']
})
export class EmailComponent implements OnInit {
  @Input()
  public email: string = "";
  public label: string = "";
  public error: string = "";
  public validate: Subject<any> = new Subject();

  constructor(
    private _validateEmailService: ValidateEmailService
  ) {}

  ngOnInit() {
    this.validate
      .pipe(debounceTime(600))
      .subscribe(() => {
        this._validateEmailService.validateEmail(this.email).subscribe( (userEmailVerification: UserEmailVerification) => {
          if (userEmailVerification.valid === true) {
            this.error = "";
          } else {
            this.error = "This is not a valid email address.";
          }
        });
        }
      );
  }

  public input(e) {
    this.validate.next();
  }
}

然后我将 导入EmailComponent到处理表单的组件中,并EmailComponent在表单视图中包含 's 选择器元素。的EmailComponent视图如下所示:

<label>
  {{ this.label }}
  <input type="text" name="email" class="email" placeholder="bob.smith@someemail.com" [(ngModel)]="email"
     (input)="this.input($event)">
  <p class="error" *ngIf="this.error">{{ this.error }}</p>
</label>

这有效,并且当您输入电子邮件时,去抖动会起作用并按预期给出验证错误。但是,它没有连接到父组件/表单,因此验证无关紧要,并且在表单中填写它不会更新父组件。

我的问题是双重的,这是实现自定义电子邮件验证器的最佳角度方式,以便它可以在多个位置使用?如果不是,那是什么?如果是,我如何连接这两个组件,以便验证的电子邮件组件/字段映射到父组件的属性?

标签: angular

解决方案


刚刚在根 email.ts 上的 angular6 项目验证器/email.ts 中创建了一个文件:

import { FormControl } from '@angular/forms';
export class EmailValidator {

    static isValid(control: FormControl) {
        const re = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/.test(control.value);

        if (re) {
            return null;
        }

        return {
            "invalidEmail": true
        };

    }
}

然后在我想在 component.ts 文件中验证它的组件中,

import { EmailValidator } from '../validator/email';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

export class CreateComponent implements OnInit, AfterViewInit {
  createForm: FormGroup;
constructor(public formBuilder: FormBuilder) {
    this.validateForm()
  }
 validateForm() {
    this.createForm= this.formBuilder.group({

      email: ['', Validators.compose([Validators.required, EmailValidator.isValid])],

    })
  }
}

现在在 component.html 中,您可以在其中向 valdate 输入电子邮件:

    <form [formGroup]="AgentForm" novalidate>
<div>
     <input type="email" class="form-control" [(ngModel)]="this.email" formControlName="email" placeholder="Enter email">
        </div>
//error message you want to show
<div *ngIf="!createForm.controls.email.valid  &&
        createForm.controls.email.dirty">
          <span>Invalid email address.</span>
        </div>
</form>

推荐阅读