码迷,mamicode.com
首页 > 其他好文 > 详细

angular2-表单验证

时间:2017-11-08 13:08:24      阅读:326      评论:0      收藏:0      [点我收藏+]

标签:个数   参考手册   exp   自定义   oid   因此   inpu   有一个   检查   

模板驱动验证

每当表单控件中的值发生变化时,Angular 就会进行验证,并生成一个验证错误的列表(对应着INVALID状态)或者null(对应着VALID状态)

我们可以通过把ngModel导出成局部模板变量来查看该控件的状态。 比如下面这个例子就把NgModel导出成了一个名叫name的变量

<input
    id="name" 
    name="name" 
    required 
    minlength="4" 
    forbiddenName="bob"
    [(ngModel)]="hero.name" 
    #name="ngModel" >
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>
</div>    

 

<input>元素带有一些HTML验证属性:required 和 minlength。它还带有一个自定义的验证器指令forbiddenName。要了解更多信息,参见自定义验证器一节。

 

#name="ngModel"NgModel导出成了一个名叫name的局部变量。NgModel把自己控制的FormControl实例的属性映射出去,让我们能在模板中检查控件的状态,比如validdirty。要了解完整的控件属性,参见 API 参考手册中的AbstractControl

 

 

<div>元素的*ngIf揭露了一套嵌套消息divs,但是只在有“name”错误和控制器为dirty或者touched

 

 

每个嵌套的<div>为其中一个可能出现的验证错误显示一条自定义消息。比如 requiredminlength和 forbiddenName

 

为何检查dirty和touched?

不希望 在用户 还没有编辑过表单的时候就给他们显示错误提示。 对dirtytouched的检查可以避免这种问题。改变控件的值会改变控件的dirty(脏)状态,而当控件失去焦点时,就会改变控件的touched(碰过)状态。

 

响应式表单的验证

响应式表单中,真正的源码都在组件类中。我们不应该通过模板上的属性来添加验证器,而应该在组件类中直接把验证器函数添加到表单控件模型上(FormControl)。然后,一旦控件发生了变化,Angular 就会调用这些函数

有两种验证器函数:同步验证器和异步验证器。

  • 同步验证器函数接受一个控件实例,然后返回一组验证错误或null。我们可以在实例化一个FormControl时把它作为构造函数的第二个参数传进去。

  • 异步验证器函数接受一个控件实例,并返回一个承诺(Promise)或可观察对象(Observable),它们稍后会发出一组验证错误或者null。我们可以在实例化一个FormControl时把它作为构造函数的第三个参数传进去。

注意:出于性能方面的考虑,只有在所有同步验证器都通过之后,Angular 才会运行异步验证器。当每一个异步验证器都执行完之后,才会设置这些验证错误。

 

例子: 要想把这个英雄表单改造成一个响应式表单,我们还是用那些内置验证器,但这次改为用它们的函数形态

ngOnInit(): void {
  this.heroForm = new FormGroup({
    ‘name‘: new FormControl(this.hero.name, [
      Validators.required,
      Validators.minLength(4),
      forbiddenNameValidator(/bob/i)
    ]),
    ‘alterEgo‘: new FormControl(this.hero.alterEgo),
    ‘power‘: new FormControl(this.hero.power, Validators.required)
  });
}
get name() { return this.heroForm.get(‘name‘); }
get power() { return this.heroForm.get(‘power‘); }

  

<input 
    id="name" 
    class="form-control"
    formControlName="name" 
    required >
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>
</div>

 关键改动是:

  • 该表单不再导出任何指令,而是使用组件类中定义的name读取器。

  • required属性仍然存在,虽然验证不再需要它,但我们仍然在模板中保留它,以支持 CSS 样式或可访问性。

  

注意

  • name控件设置了两个内置验证器:Validators.required 和 Validators.minLength(4)。要了解更多信息,参见本章的自定义验证器一节。

  • 由于这些验证器都是同步验证器,因此我们要把它们作为第二个参数传进去。

  • 可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。

  • 这个例子添加了一些getter方法。在响应式表单中,我们通常会通过它所属的控件组(FormGroup)的get方法来访问表单控件,但有时候为模板定义一些getter作为简短形式。

 

自定义验证器

export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {‘forbiddenName‘: {value: control.value}} : null;
  };
}

  

添加响应式表单

响应式表单组件中,添加自定义验证器相当简单。你所要做的一切就是直接把这个函数传给 FormControl 上面例子的 Validators.minLength(4), forbiddenNameValidator(/bob/i)

添加到模板驱动表单:

1:我们不用直接访问FormControl实例。所以我们不能像响应式表单中那样把验证器传进去,而应该在模板中添加一个指令。

2:Angular在验证流程中的识别出指令的作用,是因为指令把自己注册到了NG_VALIDATORS提供商中,该提供商拥有一组可扩展的验证器

3:指令类实现了Validator接口,以便它能简单的与 Angular 表单集成在一起

 

@Directive({
  selector: ‘[appForbiddenName]‘,
  providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
})
export class ForbiddenValidatorDirective implements Validator {
  @Input() forbiddenName: string;
  validate(control: AbstractControl): {[key: string]: any} {
    return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, ‘i‘))(control) : null;
  }
}
//forbiddenNameValidator 返回一个方法,方法接受 参数是 control 类型

  

 另外一种写法:(校验必须输入最少一个英文)

import {Directive} from "@angular/core";
import {NG_VALIDATORS} from "@angular/forms";
import {FormControl} from "@angular/forms";

@Directive({
  selector: ‘[mustInputEnglish]‘,
  providers: [{provide: NG_VALIDATORS, useValue: (control:FormControl) => {
	  let myreg = /[a-zA-Z]/;
	  let valid = myreg.test(control.value);
	  return valid ? null : { english : true };
  }, multi:true}]
})
export class EnglishValidatorDirective {
  constructor() { }
}

  

内置验证:

class Validators {
  static min(min: number): ValidatorFn
  static max(max: number): ValidatorFn
  static required(control: AbstractControl): ValidationErrors|null
  static requiredTrue(control: AbstractControl): ValidationErrors|null
  static email(control: AbstractControl): ValidationErrors|null
  static minLength(minLength: number): ValidatorFn
  static maxLength(maxLength: number): ValidatorFn
  static pattern(pattern: string|RegExp): ValidatorFn
  static nullValidator(c: AbstractControl): ValidationErrors|null
  static compose(validators: (ValidatorFn|null|undefined)[]|null): ValidatorFn|null
  static composeAsync(validators: (AsyncValidatorFn|null)[]): AsyncValidatorFn|null
}

  

 

angular2-表单验证

标签:个数   参考手册   exp   自定义   oid   因此   inpu   有一个   检查   

原文地址:http://www.cnblogs.com/vs1435/p/7803219.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!