如何在 Angular 中为响应式表单创建自定义验证器

简介

Angular 的 @angular/forms 包提供了一个 Validators 类,支持诸如 requiredminLengthmaxLengthpattern 等有用的内置验证器。然而,可能存在需要更复杂或自定义规则进行验证的表单字段。在这种情况下,您可以使用自定义验证器。

在 Angular 中使用响应式表单时,您可以使用函数定义自定义验证器。如果验证器不需要被重复使用,它可以直接存在于组件文件中作为一个函数。否则,如果验证器需要在其他组件中重复使用,它可以存在于一个单独的文件中。

在本教程中,您将构建一个带有可重用自定义验证器的响应式表单,以检查 URL 是否符合特定条件。

先决条件

要完成本教程,您需要:

  • 在本地安装 Node.js,您可以按照《如何安装 Node.js 并创建本地开发环境》进行操作。
  • 一些关于设置 Angular 项目的基本知识。

本教程已经在 Node v15.2.1、npm v6.14.8、@angular/core v11.0.0 和 @angular/forms v11.0.0 下进行了验证。

步骤 1 -- 设置项目

为了本教程的目的,您将从使用 @angular/cli 生成的默认 Angular 项目开始构建。

command 复制代码
npx @angular/cli new angular-reactive-forms-custom-validtor-example --style=css --routing=false --skip-tests

这将配置一个新的 Angular 项目,其中样式设置为 "CSS"(而不是 "Sass"、"Less" 或 "Stylus"),没有路由,并且跳过了测试。

进入新创建的项目目录:

command 复制代码
cd angular-reactive-forms-custom-validator-example

为了使用响应式表单,您将使用 ReactiveFormsModule 而不是 FormsModule

在代码编辑器中打开 app.module.ts 并添加 ReactiveFormsModule

typescript 复制代码
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

到此为止,您应该已经拥有一个带有 ReactiveFormsModule 的新 Angular 项目。

步骤 2 -- 构建自定义验证器

本教程的示例自定义验证器将接受一个 URL 字符串,并确保它以 https 协议开头并以 .io 顶级域名结尾。

首先,在您的终端中,创建一个 shared 目录:

command 复制代码
mkdir src/shared

然后,在这个新目录中,创建一个新的 url.validator.ts 文件。在代码编辑器中打开此文件并添加以下代码:

typescript 复制代码
import { AbstractControl } from '@angular/forms';

export function ValidateUrl(control: AbstractControl) {
  if (!control.value.startsWith('https') || !control.value.includes('.io')) {
    return { invalidUrl: true };
  }
  return null;
}

这段代码使用了 AbstractControl 类,它是 FormControlFormGroupFormArray 的基类。这允许访问 FormControl 的值。

这段代码将检查值是否以 https 字符串开头。它还将检查值是否包含 .io 字符串。

如果验证失败,它将返回一个带有错误名称 invalidUrl 和值 true 的对象。

否则,如果验证通过,它将返回 null

到此为止,您的自定义验证器已经准备就绪。

步骤 3 -- 使用自定义验证器

接下来,创建一个表单,其中包含 userNamewebsiteUrl

打开 app.component.ts 并用以下代码替换内容:

typescript 复制代码
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { ValidateUrl } from '../shared/url.validator';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      userName: ['', Validators.required],
      websiteUrl: ['', [Validators.required, ValidateUrl]]
    });
  }

  saveForm(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Username', form.value.userName);
    console.log('Website URL', form.value.websiteUrl);
  }
}

在这段代码中,websiteUrl 表单控件同时使用了内置的 Validators.required 和自定义的 ValidateUrl 验证器。

第四步 -- 访问模板中的错误信息

与您的表单交互的用户需要了解哪些数值未通过验证。在组件模板中,您可以使用自定义验证器返回值中定义的键。

打开 app.component.html 并用以下代码替换内容:

html 复制代码
<form [formGroup]="myForm" (ngSubmit)="saveForm(myForm)">
  <div>
    <label>
      用户名:
      <input formControlName="userName" placeholder="您的用户名">
    </label>
    <div *ngIf="(
                 myForm.get('userName').dirty ||
                 myForm.get('userName').touched
                ) &&
                myForm.get('userName').invalid"
    >
      请提供您的用户名。
    </div>
  </div>
  <div>
    <label>
      网站 URL:
      <input formControlName="websiteUrl" placeholder="您的网站">
    </label>
    <div
      *ngIf="(
              myForm.get('websiteUrl').dirty ||
              myForm.get('websiteUrl').touched
             ) &&
             myForm.get('websiteUrl').invalid"
      >
      仅接受通过 HTTPS 提供且来自 .io 顶级域的 URL。
    </div>
  </div>
</form>

此时,您可以编译您的应用程序:

command 复制代码
npm start

然后在您的网络浏览器中打开它。您可以与 userNamewebsiteUrl 字段进行交互。确保您的 ValidateUrl 的自定义验证器对于应满足 https.io 条件的值(例如 https://example.io)能够正常工作。

结论

在本文中,您为 Angular 应用程序中的响应式表单创建了一个可重用的自定义验证器。

要了解模板驱动表单和响应式表单中自定义验证器的示例,请参阅 Angular 中的自定义表单验证。

如果您想了解更多关于 Angular 的知识,请查看我们的 Angular 主题页面,了解练习和编程项目。

相关推荐
青灯文案15 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_7482548810 分钟前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.22 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营26 分钟前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端1 小时前
0基础学前端-----CSS DAY9
前端·css
joan_851 小时前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
还是大剑师兰特1 小时前
什么是尾调用,使用尾调用有什么好处?
javascript·大剑师·尾调用
m0_748236111 小时前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript