如何在 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 主题页面,了解练习和编程项目。

相关推荐
李长渊哦2 小时前
深入理解 JavaScript 中的全局对象与 JSON 序列化
开发语言·javascript·json
Senar4 小时前
如何判断浏览器是否开启硬件加速
前端·javascript·数据可视化
HtwHUAT5 小时前
实验四 Java图形界面与事件处理
开发语言·前端·python
利刃之灵5 小时前
01-初识前端
前端
codingandsleeping5 小时前
一个简易版无缝轮播图的实现思路
前端·javascript·css
天天扭码5 小时前
一分钟解决 | 高频面试算法题——最大子数组之和
前端·算法·面试
全宝5 小时前
🌏【cesium系列】01.vue3+vite集成Cesium
前端·gis·cesium
拉不动的猪6 小时前
简单回顾下插槽透传
前端·javascript·面试
烛阴6 小时前
Fragment Shader--一行代码让屏幕瞬间变黄
前端·webgl
爱吃鱼的锅包肉6 小时前
Flutter路由模块化管理方案
前端·javascript·flutter