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

简介

ANGLING的@ANGLING/forms包附带了一个Validators类,该类支持有用的内置验证器,如Required dminLengthMaxLengthpattern。但是,可能有一些表单域需要更复杂的规则或自定义规则来进行验证。在这些情况下,您可以使用自定义验证器。

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

在本教程中,您将使用可重用的自定义验证器构建一个反应式表单,以检查URL是否满足某些条件。

前提条件

要完成本教程,您需要:

本教程通过了Node v15.2.1、npmv6.14.8、@angular/corev11.0.0、@angular/formsv11.0.0验证。

第一步-设置项目

在本教程中,你将从一个默认的Angular项目中构建,该项目是用@angular/python生成的。

1npx @angular/cli new angular-reactive-forms-custom-validtor-example --style=css --routing=false --skip-tests

这将配置一个新的Angular项目,样式设置为),没有路由,并跳过测试。

导航到新创建的项目目录:

1cd angular-reactive-forms-custom-validator-example

要使用反应式表单,您将使用Reactive FormsModule而不是FormsModule

在您的代码编辑器中打开app.mode.ts,添加Reactive FormsModule

 1[label src/app/app.module.ts]
 2import { BrowserModule } from '@angular/platform-browser';
 3import { NgModule } from '@angular/core';
 4import { ReactiveFormsModule } from '@angular/forms';
 5
 6import { AppComponent } from './app.component';
 7
 8@NgModule({
 9  declarations: [
10    AppComponent
11  ],
12  imports: [
13    BrowserModule,
14    ReactiveFormsModule,
15  ],
16  providers: [],
17  bootstrap: [AppComponent]
18})
19export class AppModule { }

此时,您应该有了一个带有Reactive FormsModule的新角度投影。

第二步-自定义校验器

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

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

1mkdir src/shared

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

1[label src/shared/url.validator.ts]
2import { AbstractControl } from '@angular/forms';
3
4export function ValidateUrl(control: AbstractControl) {
5  if (!control.value.startsWith('https') || !control.value.includes('.io')) {
6    return { invalidUrl: true };
7  }
8  return null;
9}

此代码使用通知AbstractControl类,它是FormControls、FormGroups和FormArrays的基类。这允许访问FormControl`的值。

这段代码将检查startsWith值是否为Https的字符串。它还将检查值是否包括.io`的字符串。

如果验证失败,它将返回一个对象,其中包含错误名称的键validUrl,值为true

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

此时,您的自定义验证器已经可以使用了。

第三步-使用自定义验证器

接下来,创建一个带有userNamewebsiteUrl的表单。

打开app.Component.ts,将内容替换为以下几行代码:

 1[label src/app/app.component.ts]
 2import { Component, OnInit } from '@angular/core';
 3import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 4
 5import { ValidateUrl } from '../shared/url.validator';
 6
 7@Component({
 8  selector: 'app-root',
 9  templateUrl: './app.component.html',
10  styleUrls: ['./app.component.css']
11})
12export class AppComponent implements OnInit {
13  myForm: FormGroup;
14
15  constructor(private fb: FormBuilder) {}
16
17  ngOnInit() {
18    this.myForm = this.fb.group({
19      userName: ['', Validators.required],
20      websiteUrl: ['', [Validators.required, ValidateUrl]]
21    });
22  }
23
24  saveForm(form: FormGroup) {
25    console.log('Valid?', form.valid); // true or false
26    console.log('Username', form.value.userName);
27    console.log('Website URL', form.value.websiteUrl);
28  }
29}

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

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

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

打开app.component.html,将内容替换为以下代码行:

 1[label src/app/app.component.html]
 2<form [formGroup]="myForm" ngSubmit)="saveForm(myForm)">
 3  <div>
 4    <label>
 5      Username:
 6      <input formControlName="userName" placeholder="Your username">
 7    </label>
 8    <div *ngIf="(
 9                 myForm.get('userName').dirty ||
10                 myForm.get('userName').touched
11                ) &&
12                myForm.get('userName').invalid"
13    >
14      Please provide your username.
15    </div>
16  </div>
17  <div>
18    <label>
19      Website URL:
20      <input formControlName="websiteUrl" placeholder="Your website">
21    </label>
22    <div
23      *ngIf="(
24              myForm.get('websiteUrl').dirty ||
25              myForm.get('websiteUrl').touched
26             ) &&
27             myForm.get('websiteUrl').invalid"
28      >
29      Only URLs served over HTTPS and from the .io top-level domain are accepted.
30    </div>
31  </div>
32</form>

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

1npm start

然后在浏览器中打开它。您可以与userNamewebsiteUrl字段进行交互。确保您的自定义验证程序ValidateUrl按预期工作,其值应满足https.io的条件:example.io

结论

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

有关模板驱动表单和反应式表单中的自定义验证器的示例,请参考Angular.中的自定义表单验证

如果您想了解更多有关ANGLE的信息,请查看我们的ANGLE主题页面以获取练习和编程项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus