Angular Material Form field 校验详解

栏目: 编程语言 · AngularJS · 发布时间: 7年前

内容简介:在Material的官方文档中,我们可以看到在官方的例子下,我们可以得到如下的效果:

Angular Material Form field 校验详解

概述

在Material的官方文档中,我们可以看到 Form field 组件中提供了错误信息提示的封装,例子如下:

1<div class="example-container">
2  <mat-form-field>
3    <input matInput placeholder="Enter your email" [formControl]="email" required>
4    <mat-error *ngIf="email.invalid">{{getErrorMessage()}}</mat-error>
5  </mat-form-field>
6</div>
 1import {Component} from '@angular/core';
 2import {FormControl, Validators} from '@angular/forms';
 3
 4/** @title Form field with error messages */
 5@Component({
 6  selector: 'form-field-error-example',
 7  templateUrl: 'form-field-error-example.html',
 8  styleUrls: ['form-field-error-example.css'],
 9})
10export class FormFieldErrorExample {
11  email = new FormControl('', [Validators.required, Validators.email]);
12
13  getErrorMessage() {
14    return this.email.hasError('required') ? 'You must enter a value' :
15        this.email.hasError('email') ? 'Not a valid email' :
16            '';
17  }
18}

在官方的例子下,我们可以得到如下的效果:

Angular Material Form field 校验详解
image.png
Angular Material Form field 校验详解
image.png

我们可以看到 mat-error 是需要放置到 mat-form-field 内部的。只有放在内部的情况下,才可以实现动画的效果。

进阶

要实现上面的两种错误校验,需要在FormControl中设置相应的Validators。FormControl支持的校验方式我们可以归结为两种: sync和async。

sync同步校验

像前面例子中的 Validators.requiredValidators.email 就是sync同步校验。同步校验指的是在用户数据后就同步的进行校验,可以实时的对输入内容进行校验反馈。

async异步校验

异步校验主要应用于与后台有交互的情景,比如要填写一个编号,系统要求编号是唯一的,此时我们输入的值就数据发送到后台进行校验,确保当前值系统中不存在。

异步实例:

 1import {Component} from '@angular/core';
 2import {FormControl, Validators} from '@angular/forms';
 3import { HttpClient } from '@angular/common/http';
 4
 5/** @title Form field with error messages */
 6@Component({
 7  selector: 'form-field-error-example',
 8  templateUrl: 'form-field-error-example.html',
 9  styleUrls: ['form-field-error-example.css'],
10})
11export class FormFieldErrorExample {
12
13  constructor(private http: HttpClient) {}
14  email = new FormControl('', [Validators.required, Validators.email], [this.asyncValidator()]);
15
16  getErrorMessage() {
17    return this.email.hasError('required') ? 'You must enter a value' :
18        this.email.hasError('email') ? 'Not a valid email' :
19            '';
20  }
21
22
23  asyncValidator(): AsyncValidatorFn {
24    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
25
26      const email = control.value;
27
28      return this.http.get('/validate/' + email).pipe(
29          map((data) => return data.length > 0 ? {exist: true, msg: 'Duplicate email'} : null;)
30      );
31    };
32  }
33}

组合异步校验

基于上面的例子,我们再添加一个手机号的字段,现在我们的需求是手机号+邮箱组合不能重复。那么我们应该怎么实现这个异步校验呢?

可以肯定的是,组合校验的实现套路和上面的单个字段异步校验时一样的,只是需要我们在单个字段异步校验的基础上进行相应的扩展。

 1asyncValidator(phoneCtr: AbstractControl): AsyncValidatorFn {
 2    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
 3      const phone = phoneCtr.value;
 4      const email = control.value;
 5
 6      return this.http.get('/validate/' + email + '/' + phone).pipe(
 7          map((data) => return data.length > 0 ? {exist: true} : null;)
 8      );
 9    };
10  }

这样我们在声明Control的时候,也需要进行相应的调整:

 1export class FormFieldErrorExample {
 2
 3  constructor(private http: HttpClient) {}
 4  phone = new FormControl('');
 5  email = new FormControl('', [Validators.required, Validators.email], [this.asyncValidator(phone)]);
 6
 7  getErrorMessage() {
 8    return this.email.hasError('required') ? 'You must enter a value' :
 9        this.email.hasError('email') ? 'Not a valid email' :
10       this.email.hasError('exist') ? 'Duplicate email and phone combination' 
11            '';
12  }
13
14  asyncValidator(phoneCtr: AbstractControl): AsyncValidatorFn {
15    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
16      const phone = phoneCtr.value;
17      const email = control.value;
18
19      if (!phone || !email) {
20        return of(null);
21      }
22      return this.http.get('/validate/' + email + '/' + phone).pipe(
23          map((data) => return data.length > 0 ? {exist: true} : null;)
24      );
25    };
26  }
27}

我们在输入phone后,再输入email,会触发这个异步校验。此时的异步校验只有在email的内容变更时才会触发。

那么问题又来了,我们可能先输入email,再输入phone,该怎么触发这个异步校验呢?

我们可以通过监听phone的变更然后出通知email去触发校验:

1this.phone.valueChanges.subscribe(() => {
2        // this.repaymentTypeControl.markAsTouched(); 
3    this.repaymentTypeControl.updateValueAndValidity()
4});

结论

在实际开发的过程中,我们要开发各种各样的校验,有些校验规则的实现方式没有现成的例子,此时就需要我们自己去阅读框架的源码,从中找寻那一点点的曙光。


以上所述就是小编给大家介绍的《Angular Material Form field 校验详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具