MST

星途 面试题库

面试题:Angular模板驱动表单提交过程中如何处理异步验证及错误处理

在一个Angular模板驱动表单中有一个邮箱输入框,要求在用户输入后实时进行异步验证,检查该邮箱是否已在数据库中存在。若邮箱已存在,在表单提交时阻止提交并显示相应错误信息。请描述实现此功能的完整思路,包括如何设置异步验证器、如何在提交时处理错误以及如何在模板中显示错误信息。并给出关键代码示例。
13.8万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 设置异步验证器
    • 创建一个自定义异步验证器函数,该函数接收AbstractControl作为参数。
    • 在函数内部,通过HTTP服务向服务器发送请求,检查邮箱是否存在于数据库中。
    • 根据服务器响应返回Observable<ValidationErrors | null>,若邮箱存在则返回包含错误信息的对象,否则返回null
  2. 在提交时处理错误
    • 在表单提交事件处理函数中,检查表单的有效性。
    • 如果表单无效,阻止提交,并可以遍历表单控件错误信息,做相应处理。
  3. 在模板中显示错误信息
    • 使用ngIf指令结合表单控件的hasError方法,根据错误类型显示相应的错误信息。

关键代码示例

  1. 自定义异步验证器(假设使用RxJS和HttpClient)
    import { Injectable } from '@angular/core';
    import { AbstractControl, AsyncValidator, ValidationErrors, NG_ASYNC_VALIDATORS } from '@angular/forms';
    import { Observable } from 'rxjs';
    import { map, catchError } from 'rxjs/operators';
    import { HttpClient } from '@angular/common/http';
    
    @Injectable({ providedIn: 'root' })
    export class EmailExistsValidator implements AsyncValidator {
      constructor(private http: HttpClient) {}
    
      validate(control: AbstractControl): Observable<ValidationErrors | null> {
        const email = control.value;
        return this.http.get<any>(`/api/check - email?email=${email}`).pipe(
          map(response => {
            if (response.exists) {
              return { emailExists: true };
            }
            return null;
          }),
          catchError(() => {
            return new Observable<null>(observer => {
              observer.next(null);
              observer.complete();
            });
          })
        );
      }
    }
    
  2. 在模块中注册异步验证器
    import { NgModule } from '@angular/core';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { EmailExistsValidator } from './email - exists.validator';
    
    @NgModule({
      imports: [FormsModule, ReactiveFormsModule],
      providers: [
        {
          provide: NG_ASYNC_VALIDATORS,
          useExisting: EmailExistsValidator,
          multi: true
        }
      ]
    })
    export class AppModule {}
    
  3. 模板驱动表单(假设使用ngModel)
    <form #emailForm="ngForm" (ngSubmit)="onSubmit(emailForm)">
      <input type="email" name="email" [(ngModel)]="email" required
             [asyncValidators]="[emailExistsValidator]" #emailInput="ngModel">
      <div *ngIf="emailInput.hasError('emailExists') && (emailInput.touched || emailInput.dirty)">
        该邮箱已存在
      </div>
      <button type="submit" [disabled]="emailForm.invalid">提交</button>
    </form>
    
  4. 组件中的提交处理函数
    import { Component } from '@angular/core';
    import { NgForm } from '@angular/forms';
    
    @Component({
      selector: 'app - email - form',
      templateUrl: './email - form.component.html'
    })
    export class EmailFormComponent {
      email: string;
    
      constructor(private emailExistsValidator: EmailExistsValidator) {}
    
      onSubmit(form: NgForm) {
        if (form.invalid) {
          return;
        }
        // 处理表单提交逻辑,例如发送数据到服务器
      }
    }