如何为多字段创建Formly异步验证(各字段调用不同API)
通用Formly多字段异步验证方案
不用为每个字段写单独的自定义验证器,我们可以搞一个通用的异步验证器工厂函数,传不同的API地址就能生成对应字段的验证逻辑,完美适配你说的用户名、银行账号这类不同API的场景。
实现步骤
1. 写一个通用的异步验证器工厂
这个工厂函数接收HttpClient和API地址,返回对应的异步验证逻辑:
import { AbstractControl } from '@angular/forms'; import { HttpClient } from '@angular/common/http'; export function createAsyncApiValidator(http: HttpClient, apiUrl: string) { return (control: AbstractControl) => { if (!control.value) { // 空值不触发异步验证,必填逻辑交给必填验证器就行 return Promise.resolve(null); } return http.post<{ valid: boolean }>(apiUrl, { value: control.value }) .then(res => { // 根据API返回的valid字段判断,没问题就返回null,否则返回错误标记 return res.valid ? null : { apiDuplicate: true }; }) .catch(() => { // 请求失败默认算验证不通过,也可以改成返回null忽略错误 return { apiDuplicate: true }; }); }; }
2. 在表单组件里配置字段
注入HttpClient后,给每个需要异步验证的字段调用这个工厂函数,传入对应的API地址就行:
import { Component } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { FormlyFieldConfig } from '@ngx-formly/core'; import { HttpClient } from '@angular/common/http'; import { createAsyncApiValidator } from './path-to-your-validators'; @Component({ selector: 'app-demo-form', template: ` <form [formGroup]="form" (ngSubmit)="handleSubmit()"> <formly-form [form]="form" [fields]="fields" [model]="formModel"></formly-form> <button type="submit" [disabled]="!form.valid">提交</button> </form> `, }) export class DemoFormComponent { form = new FormGroup({}); formModel: any = {}; fields: FormlyFieldConfig[]; constructor(private http: HttpClient) { this.fields = [ { key: 'username', type: 'input', templateOptions: { label: '用户名', required: true, placeholder: '请输入用户名' }, validators: { // 传入用户名验证的API地址 async: [createAsyncApiValidator(this.http, 'api/username-check')] }, validationMessages: { apiDuplicate: '这个用户名已经被注册了' } }, { key: 'bankAccount', type: 'input', templateOptions: { label: '银行账号', required: true, placeholder: '请输入银行账号' }, validators: { // 传入银行账号验证的API地址 async: [createAsyncApiValidator(this.http, 'api/bankaccount-check')] }, validationMessages: { apiDuplicate: '该银行账号已绑定其他账户' } } ]; } handleSubmit() { if (this.form.valid) { console.log('表单数据:', this.formModel); // 提交逻辑 } } }
3. 按需调整细节
- 如果你的API返回格式不是
{ valid: boolean },比如返回{ exists: boolean },直接改工厂函数里的判断逻辑就行,比如return !res.exists ? null : { apiDuplicate: true } - 空值处理逻辑可以根据需求改,比如如果字段非必填但输入后才验证,现在的逻辑就刚好;如果要空值也触发验证,删掉那行空值判断就行
- 错误信息可以通过
validationMessages自定义,对应验证器返回的错误键名
内容的提问来源于stack exchange,提问作者Maarten Heideman
相关产品推荐
相关产品推荐

