简介
ANGLING的@ANGLING/forms
包附带了一个Validators
类,该类支持有用的内置验证器,如Required d
、minLength
、MaxLength
和pattern
。但是,可能有一些表单域需要更复杂的规则或自定义规则来进行验证。在这些情况下,您可以使用自定义验证器。
在Angular中使用Reactive Forms时,您可以使用函数定义自定义验证器。如果验证器不需要重用,它可以直接作为组件文件中的函数存在。否则,如果验证器需要在其他组件中重用,它可以存在于单独的文件中。
在本教程中,您将使用可重用的自定义验证器构建一个反应式表单,以检查URL是否满足某些条件。
前提条件
要完成本教程,您需要:
- 本地安装Node.js,可以按照如何安装Node.js并创建本地开发环境操作。
- 熟悉设置Angular项目。
本教程通过了Node v15.2.1、npm
v6.14.8、@angular/core
v11.0.0、@angular/forms
v11.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
。
此时,您的自定义验证器已经可以使用了。
第三步-使用自定义验证器
接下来,创建一个带有userName
和websiteUrl
的表单。
打开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
然后在浏览器中打开它。您可以与userName
和websiteUrl
字段进行交互。确保您的自定义验证程序ValidateUrl
按预期工作,其值应满足https
和.io
的条件:example.io
。
结论
在本文中,您为角度应用程序中的反应表单创建了一个可重用的自定义验证器。
有关模板驱动表单和反应式表单中的自定义验证器的示例,请参考Angular.中的自定义表单验证
如果您想了解更多有关ANGLE的信息,请查看我们的ANGLE主题页面以获取练习和编程项目。