第五章 angular中的表单

Angular中的表单
  1. 表单控件FormControl:封装了表单的输入,并提供了一些可供操作的对象。
  2. 验证器validator:让我们能够以自己喜欢的任何方式验证表单的输入。
  3. 观察者observer:让我们能够监听表单的变化,并作出相应的回应。
FormControlFormGroup
  1. Angular中最基础的两个表单对象。
  2. FormControl代表单一的输入字段,它是Angular表单中的最小单元。
  3. FormControl封装了这些字段的值和状态,比如是否有效,是否脏(被修改过),或是否有错误等。
let nameControl = new FormControl("Nate");
let name = nameControl.value;    //Nate
  1. FormGroup可以为一组FormControl提供总包接口(wrapper interface),从而来管理多个FormControl
  2. 当我们试图从FormGroup中获取value时,会收到一个“键值对”结构的对象。它能让我们从表单中一次性获取全部的值而无需逐一遍历FormControl
let personInfo = new FromGroup({
  firstName: new FormControl("Nate"),
  lastName: new FormControl("Murray"),
  zip: new FormControl("90210")
})

personInfo.value;
/*{
		firstName : "Nate",
		lastName: "Murray",
		zip : "90210"
	}
*/
Angular中两种使用表单的方式
  1. FormsModule为我们提供了一些模板驱动。(ngModel ngForm)。
  2. ReactiveFormsModule提供了下列指令(formControl ngFormGroup)。
<div class="ui raised segment">
  	<h2 class="ui header">Demo Form : Sku</h2>
      <form #f="ngForm"
            	  (ngSubmit)="onSubmit(f.value)"
           		 class="ui form">
        <div class="field">
          	<label for="skuInput">SKU</label>
          	<input type="text"
                   		 id="skuInput"
                   		placeholder="SKU"
                   		name="sku" ngModel>
        </div>   
        <button type="submit"  ></button>
</div>
  1. 导入FormsModule之后,就可以在视图中使用NgForm了,当这些指令在视图中可用时,它就会被附加到任何能匹配其selector的节点上。
  2. NgForm做了一件便利但隐晦的工作:它的选择器包含form标签(而不用显示添加ngForm属性),这意味着当我们导入FormsModule的时候,NgForm就会被自动附加到视图中所有的<form>标签上。
  3. NgForm提供了两个重要的功能:
    • 一个名叫ngFormFormGroup对象。
    • 一个输出事件(ngSubmit)。
    • #v=thing语法的意思是:在当前视图中创建一个局部变量。这里我们为ngForm创建了一个别名,并绑定到变量#f上。
  4. ngFormFormGroup类型,这意味着我们可以把变量f当作FormGroup使用。而这也正是在输出事件(ngSubmit)中的使用方法。
  5. 如果ngForm是属性的键,那就是在告诉Angular,我们要根据这个属性使用NgForm指令。但在这里我们要对一个引用赋值,而把ngForm用作属性值。这表示把ngForm这个表达式的执行结果赋值给局部模板变量f
  6. 既然ngForm在这个节点上,那么这个f变量是FormGroup类型,那么就可以在视图中的任何地方引用它。
  7. 即:当提交表单时,将会以表单的值作为参数,调用组件实例上的onSubmit方法。
  8. NgModel指令指定的是selectorngModel,这意味着我们可以通过添加这个属性把它附加到input标签上:ngModel="whatever",在这里我们指定了一个不带属性值的的ngModel
  9. 有两种不同的方法能在模板中指定ngModel
  10. 当使用不带属性值的ngModel时,我们要指定:
    • 单向数据绑定。
    • 希望在表单中创建一个名为skuFormControl(这个sku来自input标签上的name属性)。NgModel会创建一个新的FormControl对象,把它自动添加到父FormGroup上。(这里也就是form表单对象)。并把这个FormControl对象绑定到一个DOM上。即它会在视图中的input标签和FormControl对象之间建立关联。这种关联是通过name属性建立的,本例中是sku
  11. NgModelngModel区别:
    • NgModelPascal命名法,指的是类和供代码中引用的对象。
    • ngModel是小写的驼峰命名法,来自指令的选择器selector,并且只会被用在DOM/模板上。
  12. NgModelFormControl并不是同一个,ngModel是用在视图中的指令,FormControl是用来表示表单中的数据和验证规则的。
FormBuilder响应式表单
  1. FormBuilder是表单构建助手,表单是由FormControlFormGroup构成的,而FormBuilder则可以帮助我们创建它们。
import { FormBuilder, FormGroup} from '@angular/forms';

export class DemoFormSkuBuilder {
  myForm: FormGroup;
  
  constructor(fb: FormBuilder){
    this.myForm = fb.group({
      'sku' : ['ABC123']
    })
  }
  
  onSubmit(value : string) : void{
    console.log('you submitted value : ' , value);
  }
}
  1. Angular将会注入一个从FormBuilder类创建的对象实例,并把它赋给变量fb

  2. 将使用FormBuilder中两个主要的函数:

    • control,用于创建一个新的FormControl
    • group,用于创建一个新的FormGroup
  3. myFormFormGroup类型,我们通过调用fb.group()来创建FormGroup.group方法的参数代表组件内各个FormControl的键值对。

  4. 在视图中使用myForm

<h2 class = "ui header">Demo Form: sku with Builder</h2>
  <form [formGroup] ="myForm"> 
    <div class = "field">
      	<label for="skuInput">SKU</label>
      	<input type="text" id="skuInput" placeholder="SKU"  [formControl]="myForm.controls['sku']">
    </div>
</form>
  1. 如果想要隐式的创建新的FormGroupFormControl,使用ngForm ngModel
  2. 如果要绑定一个现有的FormGroupFormControl,使用formGroup formControl
添加验证
  1. 验证器由Validators模块提供,Validators.required是最简单的验证,表明指定的字段是必填项,否则就认为这个FormControl是无效的。
  2. 使用验证器
    • FormControl对象指定一个验证器。(可以直接把它作为第二个参数传给FormControl的构造函数。)
    • 在视图中检查验证器的状态,并据此采取行动。
let control = new FormControl('sku', Validators.required);

  constructor(fb: FormBuilder){
    this.myForm = fb.group({
      'sku' : ['',  alidators.required]
    })
  }
  
在视图中使用验证
  1. 显式的把sku设置为实例变量。
export class DemoFormWithValidationsExplicit {
  myForm: FormGroup;
  sku : AbstracControl;
  
  constructor(fb: FormBuilder){
    this.myForm = fb.group({
      'sku' : ['',  alidators.required]
    })
    this.sku= this.myForm.controls['sku'];
  }
  
  onSubmit(value : string) : void{
    console.log('you submitted value : ' , value);
  }
}
  1. 验证整个表单的有效性
<div *ngIf = "!sku.valid" class="ui error message">
  	SKU is  invalid
</div>
  1. FormControl无效时,为该字段显示一条错误信息
<div *ngIf = "!sku.valid" class="ui error message">  	SKU is  invalid</div> <div *ngIf = "sku.hasError('required') " class="ui error message">  	SKU is  required</div>
  1. 字段着色
<div class="field" [class.error]="!sku.valid && sku.touched"></div>

在这里为.error类设置了两个条件:检查!sku.validsku.touched,这是因为只有当用户修改过表单后(touched)才显示错误状态。

  1. 特定验证
 <div *ngIf = "myForm.hasError('required', 'sku') " class="uerror">  	SKU is  required</div>
  1. 自定义验证器
function skuValidator(control : FormControl) : {s[: string]: boolean}{  if(!control.value.match(/^123/)){    return {invalidSku : true}  }}

当输入值不是以123作为开始时,验证器会返回错误代码invalidSku

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

Validators.compose把两个验证器包装在一起,我们可以将其赋值给FormControl,只有两个验证都合法时,FormControl才合法。

<div *ngIf="sku.hasError('invalidSku')" class="ui error message">  </div>
  1. 监听控件的变化
    • 通过调用control.valueChanges访问到这个EventEmitter
    • 然后,使用.subscribe方法添加一个监听器。
constructor( fb : FormBuilder) {  this.myForm = fb.group({    'sku' : [' ', Validators.required]  });    this.sku = this.myForm.controls['sku'];    this.sku.valueChanges.subscribe(  	(value: string)=>{      	console.log('sku changed to : ', value)    }  );    this.myForm.valueChanges.subscribe(  	(value: string)=>{      	console.log('sku changed to : ', form)    }  );}
  1. ngModel双向绑定
export class DemoFormNgModel {  myForm : FormGroup;  productName: string;    constructor( fb : FormBuilder){    this.myForm = fb.group({      'productName': [' ', Validators.required]    });  }     onSubmit(value : string) : volid{    console.log(' you submitted value:' , value)  }}
<label for="productNameInput">ProductName</label><input type="text" id="product name" [formControl]="myForm.get('productName') "  [(ngModel)]="productName">

仍然用formControl指定此input应该绑定到表单上的FormControl,因为我们还需要对这个值加以进行验证并作为表单的一部分提交上去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值