angular2 模板驱动型表单

angular2 模板驱动型表单

要使用模板驱动型表单,我们必须先导入FormsModule模块。

@NgModule({
  imports: [
    FormsModule,    //<==
    CommonModule
  ],
  ...
})

构造表单获取表单数据

template.component.html

{{form.value | json}}

template.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-template',
  templateUrl: './template.component.html'
})
export class TemplateComponent{
  constructor() { }
 
  onSubmit(value) {
    console.log('submit', value);
  }
}

几点说明:

  1. angular2 会自动为表单添加 ngForm 指令,我们不需要再单独写
    ,我们可以通过模板引用变量#form="ngForm"引用该指令,获取表单的验证信息和数据。
  2. 当给表单内元素添加 ngModel指令后,该元素会被自动添加到ngForm中,我们可以在form.controls上找到它。要注意的是,使用 ngModel指令时,必须同时给该元素添加 name 属性(name="name"),否则控制台会报错。
  3. 如果我们确实想使用ngModel,又不想给其添加name属性,我们可以设置 [ngModelOptions]="{standalone: true}",这样控制台不会报错,但该表单元素不会被添加到ngForm上。
  4. 在提交表单时我们可以通过(ngSubmit)="onSubmit(form.value)"获取表单内添加了 ngModel 指令同时设置了 name 属性的表单元素的值。

添加表单验证显示错误信息

假设namepassword都是必填的,password长度须在6到12位之间。

template.component.html


  

name can not be empty!

password can not be empty!

the maxlength of password is 12!

the minlength of password is 6!

几点说明:

  1. angular2内置了一些常见的验证器,required(必填),maxlength(最大长度),minlength(最小长度),max(最大值),min(最小值),pattern(正则表达式)...等等,我们可以直接使用它。
  2. 我们可以通过模板引用变量#name="ngModel"引用ngModel指令,来获该元素的验证信息,从而做相应的验证提示。
  3. *ngIf="name.invalid && (name.dirty || name.touched || form.submitted)",这里表示当name为脏值或者已经被访问过或者表单已经提交了,name值仍然无效时,显示错误信息,详细的状态说明可参考通过 ngModel 跟踪修改状态与有效性验证。
  4. 当元素验证失败时,我们可以通过errors属性获取具体是那一项验证没有通过,如:*ngIf="name.errors.required",表示如果errors上存在required属性,表明用户没有输入。

自定义同步验证器

假设我们需要一个可以指定验证规则的密码验证器。
password.validator.ts

import { AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms';
import {Directive, Input} from '@angular/core'

@Directive({
    selector:'[password]',
    providers: [{provide: NG_VALIDATORS, useExisting: PasswrodDirective, multi: true}]
})
export class PasswrodDirective implements Validator{
    @Input()
    password:string;
    
    validate(control:AbstractControl) {
        let error = null;
        if (this.password) {
            const reg = new RegExp(this.password, 'i');
            if (!reg.test(control.value)) {
                error = {
                    password:control.value
                }
            }
        }
        return error;
    }
}

在模板中使用


    

password is illegal!

几点说明:

  1. 验证器的本质就是一个属性型指令。
  2. angular2内置的验证器都是绑定在NG_VALIDATORS上的,我们可以通过设置providers属性对其进行扩展。
  3. 我们通过@Input()给指令添加了一个输入参数,这样我们可以指定验证规则了。
  4. 该指令的类实现了Validator接口,需要实现validate这个方法。validate方法接收一个AbstractControl类型的参数control,我们可以通过control.value获取到需要校验的值。validate方法返回null表示验证成功,返回对象(这个例子中是:{password:'test'})表示验证失败,返回的错误对象的属性会被添加到errors对象中。

自定义异步验证器

假设我们需要一个可以验证用户名是否重复的验证器。
name.validator.ts

import { AbstractControl, AsyncValidator, NG_ASYNC_VALIDATORS } from '@angular/forms';
import { Directive } from '@angular/core';

const userList = [
    'jack',
    'mary',
    'jimi',
    'tom'
];

@Directive({
    selector:'[checkName]',
    providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CheckNameDirective, multi: true}]
})
export class CheckNameDirective implements AsyncValidator{

    validate(control:AbstractControl) {
        console.log(control);
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (userList.indexOf(control.value) >= 0) {
                    resolve({
                        'checkName':control.value
                    });
                } else {
                    resolve(null);
                }
            }, 2000)
        });
    }
}

在模板中使用


    

name can not be empty!

this name is exist!

几点说明:

  1. 异步验证器的本质也是一个属性型指令。
  2. 我们可以通过设置providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CheckNameDirective, multi: true}]NG_ASYNC_VALIDATORS进行扩展。
  3. 该指令的类实现了AsyncValidator接口,需要实现validate这个方法。validate方法接收一个AbstractControl类型的参数control,我们可以通过control.value获取到需要校验的值。与同步验证器不同的是,异步验证器的validate方法返回一个Promise对象,当延时操作执行完以后,resolve(null)表示验证成功,resolve({'checkName':control.value})表示验证失败,resolve传递的数据会被附加到errors对象中。
  4. 当所有的同步验证器验证通过后,才会开始异步验证。

你可能感兴趣的:(表单验证,表单,angular2)