Angular 2 之五 表单

概述

标注方式定义表单步骤如下:

  1. 创建表单输入的数据模型
  2. 创建组件用于表单输入
  3. 创建组件模板用于表单布局
  4. 使用ngModel将数据模型字段双向绑定到对应的输入控件
  5. 输入控件增加ngControl属性
  6. 增加css视觉效果
  7. 显示或隐藏输入错误提示信息
  8. 表单数据验证正确之前禁用提交按钮
  9. 通过ngSubmit处理数据提交。

ngForm/ngControl标注方式

表单组件定义如下所示:

@Component({  
  selector: 'demo-form-sku',  
  directives: [FORM_DIRECTIVES],  
  template: `  
   <form #f="ngForm" (ngSubmit)="onSubmit(f.value)">
     <div class="field">  
       <label for="skuInput">SKU</label>  
       <input type="text" id="skuInput" placeholder="SKU" ngControl="sku">  
     </div>
     <button type="submit" class="ui button">Submit</button>  
   </form>  
})

 

directives元数据注入FORM_DIRECTIVES,模板可使用ngForm directive。一般地,directive在匹配选择器(selector)后被加入元素,但Angular 2自动将ngForm加到模板的所有

元素中,并实现以下功能:

 

  • 创建名为ngForm的ControlGroup,含ngFormModel属性除外
  • 创建名为ngSubmit的事件绑定。

因此:

  • #f=“ngForm”定义模板局部变量f,ngForm即自动创建的ControlGroup名
  • (ngSubmit)=”onSubmit(f.value)”中ngSubmit即自动创建的事件绑定,f.value即ControlGroup值,是一个控件名为key、输入值为value的JSON对象
  • ngControl=”sku”在ControlGroup中创建一个名为sku的Control,并将input元素和该Control关联,即input值和sku Control值关联
  • 注意示例仅用于输入,不包括双向数据绑定概念。

FormBuilder编程方式

上节通过ngForm和ngControl标注隐式创建ControlGroup和Control,虽然比较方便但是不够灵活,即无法定制各种选项。FormBuilder是一个工厂对象,用于编程创建ControlGroup和Control。

表单组件定义如下所示:

@Component({  
  selector: 'demo-form-sku-builder',  
  directives: [FORM_DIRECTIVES],  
  template: `  
     <form [ngFormModel]="myForm" (ngSubmit)="onSubmit(myForm.value)">
       <div class="field">  
         <label for="skuInput">SKU</label>  
         <input type="text" id="skuInput" placeholder="SKU"  
            [ngFormControl]="myForm.controls['sku']">  
       </div>
       <button type="submit" class="ui button">Submit</button>  
    </form>`
})  

 

export class DemoFormSkuBuilder {  
  myForm: ControlGroup;

  constructor(fb: FormBuilder) {  
    this.myForm = fb.group({ 'sku': ['ABC123'] });  
  }

  onSubmit(value: string): void {  
    console.log('you submitted value: ', value);  
  }
}

 

 

和上节代码的区别在于:

  • 组件构造函数注入FormBuilder对象,在构造函数中显式创建ControlGroup和名为sku的Contrrol对象
  • ControlGroup局部变量名是myForm,模板使用ngFormModal属性指定该名称
  • ngControl改为ngFormControl属性,表达式myForm.controls[‘sku’]的含义是从myForm ControlGroup的controls中获取名为sku的Control,并将input元素和该Control关联
  • 同样示例仅用于输入,不包括双向数据绑定概念。

数据校验Validator

1. 内置数据校验

为确保用户输入正确的数据格式,Angular 2使用Validator校验输入数据,内置提供以下数据校验:

  • MaxLengthValidator: 数据最大长度校验
  • MinLengthValidator: 数据最小长度校验
  • RequiredValidator: 必填字段校验
  • PatternValidator: 正则表达式模板校验

2. 5.5.2 使用数据校验

创建Control时指明数据验证条件,如:

    this.myForm = fb.group({  
      'sku':  ['', Validators.required]  
    });

如果是多个条件则采用组合方式(skuValidator是自定义的),如:

    this.myForm = fb.group({  
      'sku':  ['', Validators.compose([  
      Validators.required, skuValidator])]  
    });

3. 错误信息提示

Angular 2使用Control的CSS class反映状态:

  • 是否已访问:ng-touched和ng-untouched
  • 值是否改变:ng-dirty和ng-pristine
  • 值是否有效:ng-valid和ng-invalid 可以通过CSS类显示字段级的错误信息,如:

        <div *ngIf="!sku.control.valid" class="ui error message">
          SKU is invalid
        </div>

     

    如果该字段有多个数据校验条件,则可使用:

         <div *ngIf="sku.control.hasError('required')" class="ui error message">
            SKU is required
         </div>

     

4. 自定义数据校验

自定义数据校验如下所示:

export class Validators {  
  static required(c: Control): StringMap<string, boolean> {  
    return isBlank(c.value) || c.value == "" ? {"required": true} : null;  
}

 

其中:

  • 函数名即Validator名称
  • 输入是Control对象
  • 输出是StringMap<string, boolean> ,其中key是错误名称(error code),value等于true表示格式有误。

返回Promise<ValidationResult>可实现异步数据校验。

双向数据绑定

ngModel用于模型和表单的双向数据绑定,例如:

        <input type="text"  
           id="productNameInput"  
           placeholder="Product Name"  
           [ngFormControl]="myForm.find('productName')"  
           [(ngModel)]="productName">

 

这里使用ngFormControl是为了实现数据校验功能。

提交数据

点type=”submit”的按钮将触发ngSubmit事件。当表单数据不正确时可禁用该按钮,如:

<button type="submit" class="btn btn-default [disabled]="!heroForm.form.valid">
   Submit
</button>

 

在onSubmit()回调函数中,可获取ControlGroup值对象,其中key是控件名称,value是输入值。

输入数据变化

ControlGroup和Control的valueChanges方法返回Observable对象。subscribe 该返回对象可以获取输入值变化的异步数据流。

posted @ 2016-05-02 20:43  weisp  阅读(573)  评论(0编辑  收藏  举报