面试题答案
一键面试1. 创建自定义异步验证器
首先,创建一个用于异步验证邮箱是否已注册的服务。假设名为 EmailValidationService
:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class EmailValidationService {
constructor(private http: HttpClient) {}
checkEmailExists(email: string): Observable<boolean> {
// 假设后端接口为 /api/checkEmail,将邮箱作为参数传递
return this.http.get<{ exists: boolean }>(`/api/checkEmail?email=${email}`)
.pipe(
map(response => response.exists)
);
}
}
然后,创建自定义异步验证器函数。在 validators
文件夹下创建 asyncEmailValidator.ts
:
import { AbstractControl, AsyncValidator, ValidationErrors, NG_ASYNC_VALIDATORS } from '@angular/forms';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { EmailValidationService } from './email-validation.service';
@Injectable({
providedIn: 'root',
// 将该验证器注册到 NG_ASYNC_VALIDATORS 中
providers: [{
provide: NG_ASYNC_VALIDATORS,
useExisting: AsyncEmailValidator,
multi: true
}]
})
export class AsyncEmailValidator implements AsyncValidator {
constructor(private emailValidationService: EmailValidationService) {}
validate(control: AbstractControl): Observable<ValidationErrors | null> {
return this.emailValidationService.checkEmailExists(control.value)
.pipe(
map((exists: boolean) => {
return exists? { emailExists: true } : null;
})
);
}
}
2. 在组件中定义异步验证逻辑
在组件的 ts
文件中,引入并使用该异步验证器:
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AsyncEmailValidator } from './validators/asyncEmailValidator';
@Component({
selector: 'app-email-form',
templateUrl: './email-form.component.html',
styleUrls: ['./email-form.component.css']
})
export class EmailFormComponent {
emailForm: FormGroup;
isLoading = false;
constructor(private asyncEmailValidator: AsyncEmailValidator) {
this.emailForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email], this.asyncEmailValidator.validate.bind(this.asyncEmailValidator))
});
}
onSubmit() {
if (this.emailForm.valid) {
// 处理表单提交逻辑
}
}
}
3. 在模板中应用验证器并处理加载状态和验证失败提示
在组件的模板文件(email-form.component.html
)中:
<form [formGroup]="emailForm" (ngSubmit)="onSubmit()">
<div>
<label for="email">Email:</label>
<input type="email" id="email" formControlName="email">
<div *ngIf="emailForm.get('email').hasError('required') && (emailForm.get('email').touched || emailForm.get('email').dirty)">
Email is required.
</div>
<div *ngIf="emailForm.get('email').hasError('email') && (emailForm.get('email').touched || emailForm.get('email').dirty)">
Please enter a valid email.
</div>
<div *ngIf="emailForm.get('email').hasError('emailExists') && (emailForm.get('email').touched || emailForm.get('email').dirty)">
This email is already registered.
</div>
<div *ngIf="isLoading">Checking if email is registered...</div>
</div>
<button type="submit" [disabled]="emailForm.invalid || isLoading">Submit</button>
</form>
总结
通过上述步骤,我们创建了一个自定义的异步验证器来验证邮箱是否已在服务器端注册。在组件中正确地引入并使用了该验证器,并在模板中处理了验证过程中的加载状态和验证失败提示。这样,当用户输入邮箱时,系统会在服务器端验证邮箱的唯一性,并给出相应的提示。