介绍
角的@angular/forms
包带有一个Validators
类,支持有益的内置的验证喜欢required
,minLength
,maxLength
,和pattern
。但是,可能存在需要更复杂或自定义规则进行验证的表单字段。在这些情况下,您可以使用自定义验证器。
在 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
.
- 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
:
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 { }
此时,您应该拥有一个新的 Angular 项目ReactiveFormsModule
。
第 2 步 – 构建自定义验证器
本教程的示例自定义验证器将采用 URL 字符串并确保它以https
协议开头并以.io
顶级域结尾。
首先,在您的终端中,创建一个shared
目录:
- mkdir 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;
}
此代码使用 NoticeAbstractControl
类,它是FormControl
s、FormGroup
s 和FormArray
s的基类。这允许访问 的值FormControl
。
此代码将检查startsWith
字符串的值是否为https
. 它还将检查值是否为includes
的字符串.io
。
如果验证失败,它将返回一个对象,其中包含错误名称的键invalidUrl
和值true
。
否则,如果验证通过,它将返回null
。
此时,您的自定义验证器已准备好使用。
第 3 步 – 使用自定义验证器
接下来,创建一个包含 auserName
和 a的表单websiteUrl
。
打开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
并用以下代码行替换内容:
<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 主题页面以获取练习和编程项目。