介绍
Angular 的 @angular/forms
包带有一个 Validators
类,它支持有用的内置验证器,如 required
、minLength
、maxLength
和 [X140X ]。 但是,可能存在需要更复杂或自定义规则进行验证的表单字段。 在这些情况下,您可以使用自定义验证器。
在 Angular 中使用 Reactive Forms 时,您可以使用函数定义自定义验证器。 如果验证器不需要重用,可以直接作为函数存在于组件文件中。 否则,如果验证器需要在其他组件中重用,它可以存在于单独的文件中。
在本教程中,您将使用可重用的自定义验证器构造一个反应式表单,以检查 URL 是否满足特定条件。
先决条件
要完成本教程,您需要:
- Node.js 安装在本地,您可以按照【X57X】如何安装Node.js 并创建本地开发环境【X126X】进行。
- 熟悉 设置 Angular 项目 。
本教程已使用 Node v15.2.1、npm
v6.14.8、@angular/core
v11.0.0 和 @angular/forms
v11.0.0 进行了验证。
第 1 步 - 设置项目
就本教程而言,您将从使用 @angular/cli
生成的默认 Angular 项目构建。
npx @angular/cli new angular-reactive-forms-custom-validtor-example --style=css --routing=false --skip-tests
这将配置一个新的 Angular 项目,其样式设置为“CSS”(与“Sass”、“Less”或“Stylus”相对)、无路由和跳过测试。
导航到新创建的项目目录:
cd angular-reactive-forms-custom-validator-example
要使用响应式表单,您将使用 ReactiveFormsModule
而不是 FormsModule
。
在代码编辑器中打开 app.module.ts
并添加 ReactiveFormsModule
:
src/app/app.module.ts
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
目录:
mkdir src/shared
然后,在这个新目录中,创建一个新的 url.validator.ts
文件。 在代码编辑器中打开此文件并添加以下代码行:
src/shared/url.validator.ts
import { AbstractControl } from '@angular/forms'; export function ValidateUrl(control: AbstractControl) { if (!control.value.startsWith('https') || !control.value.includes('.io')) { return { invalidUrl: true }; } return null; }
此代码使用 Notice AbstractControl
类,它是 FormControl
s、FormGroup
s 和 FormArray
s 的基类。 这允许访问 FormControl
的值。
此代码将检查值 startsWith
是否为 https
的字符串。 它还将检查值 includes
是否为 .io
的字符串。
如果验证失败,它将返回一个对象,其键为错误名称 invalidUrl
,值为 true
。
否则,如果验证通过,它将返回 null
。
此时,您的自定义验证器就可以使用了。
第 3 步 – 使用自定义验证器
接下来,创建一个包含 userName
和 websiteUrl
的表单。
打开app.component.ts
,将内容替换为以下代码行:
src/app/app.component.ts
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
验证器。
第 4 步 – 访问模板中的错误
与您的表单交互的用户将需要有关哪些值未通过验证的反馈。 在组件模板中,您可以使用您在自定义验证器的返回值中定义的键。
打开app.component.html
,将内容替换为以下代码行:
src/app/app.component.html
<form [formGroup]="myForm" ngSubmit)="saveForm(myForm)"> <div> <label> Username: <input formControlName="userName" placeholder="Your username"> </label> <div *ngIf="( myForm.get('userName').dirty || myForm.get('userName').touched ) && myForm.get('userName').invalid" > Please provide your username. </div> </div> <div> <label> Website URL: <input formControlName="websiteUrl" placeholder="Your website"> </label> <div *ngIf="( myForm.get('websiteUrl').dirty || myForm.get('websiteUrl').touched ) && myForm.get('websiteUrl').invalid" > Only URLs served over HTTPS and from the .io top-level domain are accepted. </div> </div> </form>
此时,您可以编译您的应用程序:
npm start
并在您的网络浏览器中打开它。 您可以与 userName
和 websiteUrl
的字段进行交互。 确保 ValidateUrl
的自定义验证器按预期工作,其值应满足 https
和 .io
的条件:https://example.io
。
结论
在本文中,您为 Angular 应用程序中的响应式表单创建了一个可重用的自定义验证器。
有关模板驱动表单和响应式表单中的自定义验证器的示例,请参阅 Angular 中的自定义表单验证。
如果您想了解有关 Angular 的更多信息,请查看 我们的 Angular 主题页面 以获取练习和编程项目。