<span style="font-family:Microsoft YaHei;">
</span>

Angular2 重新设计了全新的表单模块,本文基于 angular rc.4 版本

ng2的表单有三个重要概念

1 FormControl //它封装了表单的inputs项,对外暴露为一个可以操作的FormControl对象

2 Validator //包括了一些常用的表单验证方法和一些工具函数,使得我们可以添加自定义的验证逻辑

3 Observers //检测表单的变动并执行相应的操作


FormControl 和 FormGroup

FormControl 代表单一的 input 输入域,它是 angular2/forms 的最小单元,在 FormControl中我们可以访问 input的值,当前的状态,例如是否 valid,是否 dirty,是否有 errors


在组件中创建一个FormControl:

<span style="font-family:Microsoft YaHei;">let nameControl = new FormControl("kate");
let name = nameControl.value; //kate
nameControl.errors //StringMap(string,any) of errors
nameControl.dirty //false
nameControl.valid //true</span>

于是创建表单的过程就是创建一系列FormControl并添加相应的元数据和逻辑代码的过程。在模板中这样使用一个FormControl:

<input type="text" [formControl]="name"> //form 表单中某一行

这时我们就相当于在表单form的上下文环境中创建了一个新的FormControl对象。由于大部分表单都不止一个输入域,因此,我们需要有一种方式来管理多个 FormControl,同时还需要验证我们的表单,我们可以使用循环来遍历所有的FormControl来实现,但是这样会相当笨重而且复杂,没事,ng2为我们提供了 FormGroup来解决这个问题,下面我们创建一个FormGroup:

<span style="font-family:Microsoft YaHei;">let person = new FormGroup({
name: new FormControl("issliu"),job: new FormControl('web front end develpoer'),zip: new FormControl("200000")
})</span>


在实现上,FormGroup和FormControl都继承自AbstractControl抽象类,这意味着只要是在AbstraclControl中拥有的属性和函数在这两者之间都可以使用。因此,我们同样可以查看FormGroup的状态,值,变化检测等等。


下面我们来创建一个表单:

在创建表单之前,我们需要引入相应的依赖:

import {FormGroup,FormControl,FormBuilder,Validators,AbstractControl} from '@angular/forms';
import {FORM_DIRECTIVES} from '@angular/forms';
//FORM_DIRECTIVES 模块中包含了一系列常用的表单指令,只要我们在component的directives中引用了它,就可以在对应的template中使用这些指令
@Component({
	selector: "test-form",directives: [FORM_DIRECTIVES],template: `<form #f="ngForm" (ngSubmit)="onSubmit(f.value)"><input name="sku" placeholder="sku"></input><button type="submit">submit</button></form>`
})
export class DemoForm {
	onSubmit(form:any):void{
		console.log('form data:',form);
	}
}


这样,我们就实现了一个简单的表单。
详细解释:
这里可能会比较迷惑,因为我们并没有写什么指令在form上面,唯一的变化点在我们写了一个#f="ngForm"在form表单上面而已。
其实NgForm已经帮我们完成了这一切,在初始化Angular2表单时,只要我们引入了FORM_DIRECTIVES指令,它会自动检测form标签,如果form不包含
ngNoForm指令或者没有指定formGroup属性,则会自动为form表单应用NgForm指令,具体到细节就是绑定了一个名为ngForm的FormGroup到表单上。
这是一个非常有用的特性。当NgForm指令应用到form表单上后,它使得表单具有了以下两个功能:
1 一个名为 ngForm 的 FormGroup
2 表单具有一个 ngSubmit 的 @Output 属性
 
这里的#f="ngForm"表示我们使用了一个名为f的变量引用了这个表单对象,这样我们可以在模板的其他地方访问到它。
我们使用(ngSubmit)="onSubmit(f.value)"语句为表单绑定了一个提交行为,这个 onSubmit 方法是需要我们在对应的组件里面实现的。
这句话的意思是,当点击提交表单时,请调用组件的onSubmit方法。于是我们实现了一个具有一个input标签的可以提交的表单。
2 使用FormBuilder
ng2 为我们隐式构造FormControl 和 FormGroup 是非常简单快捷的。但是,如果我们希望自定义表单的行为怎么办?FormBuilder为我们很好的
解决了这个问题。
 
从命名上我们就可以看出,FormBuilder是用于帮助我们build表单的。前面我们提到表单是由FormControl和FormGroup组成的,这里我们可以把
FormBuilder理解为生产FormControl和FormGroup的工厂。
下面我们举例如何使用FormBuilder
我们需要引入REACTIVE_FORM_DIRECTIVE,这样才能在表单中使用formGroup和formControl指令。
 
import {FORM_DIRECTIVE,REACTIVE_FORM_DIRECTIVES,FormGroup} from '@angular/form';
@Component({
	selector: "demo-form-builder",templateUrl:'demo.html',directives: [FORM_DIRECTIVES,REACTIVE_FORM_DIRECTIVES]
})
export class DemoFormBuilder{
	myForm: FormGroup;
	constructor(private fb: FormBuilder) {
		this.myForm = fb.group({
			'sku': ['ABC123']
		})
	}
	onSubmit(value){
		console.log(value);
	}
}


这里我们在构造函数中注入了一个FormBuilder实例,这个FormBuilder实例具有两个主要的方法:
1 fb.control() //构造一个FormControl实例
2 fb.group() //构造一个FormGroup实例
上面的例子中,我们构造了一个名为myForm的FormGroup实例,这个group包含一个名为sku的control,默认值为'ABC123'.
现在我们把这个组件引用到模板中:
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)">
	<input [formControl]="myForm.controls['sku']"/>
	<button type="submit">submit</button>
</form>


这里,我们显示的指明了表单的formGroup属性,因此ng2不会为表单自动应用NgForm指令了。
NgForm自动应用的form表单需要符合以下规则:
form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]
这意味着使用了ngNoForm属性的表单也不会应用NgForm
总结:
如果我们需要隐式的创建FormGroup和FormControl,请使用 ngFrom和ngModel //FORM_DIRECTIVES
如果需要绑定到一个已经存在的FormGroup和FormControl对象,请使用formGroup和formControl //REACTIVE_FORM_DIRECTIVES
3 添加验证:
在上面的DemoFormBuilder 类构造函数中,我们为this.myForm初始化值,现在改为:
this.myForm = fb.group({
	'sku': ['',Validators.required]
})


我们已经可以在模板中通过myForm.controls['sku']来访问表单的sku值了,但是这样会在模板中写很多代码,最方便快捷的,是在组件内定义
一个实例变量用来引用名为sku的FormControl,例如
sku:AbstractControl;
this.sku = this.myForm.controls['sku'];
于是在模板中我们可以直接使用sku变量。这样做的好处,是在模板的任何一个地方我们都可以快速访问sku变量,但是如果是一个非常大的表单,
我们则需要在组件中初始化很多这样的变量,使得代码体验比较糟糕。
FormControl和FormGroup都具有hasError方法,
如果我们需要验证一个FormControl,可以这么写
<div *ngIf="sku.hasError('required')"></div>
如果需要验证FormGroup的某一项,那就这么写
<div *ngIf="myForm.hasError('required','sku')"></div>
现在,让我们来自定义一个Validator吧!
function skuValidator(control:FormControl): {[s:string]: boolean} {
	if(control.value.test(/^123/)) {
		return {
			invalidSku: true
		}
	}
}


定义Validator有三个关键点:
它接受一个FormControl作为参数,同时返回一个StringMap<string,boolean>对象,如果这个boolean值为真表明验证通过,否则表明出错。
现在我们把这个验证项加入myForm:
this.myForm = fb.Group({
	'sku': ['',Validator.compose([
		validators.required,skuValidator
	])]
})

ok,大功告成,现在我们在模板中可以使用:
<div *ngIf="myForm.hasError('skuValidator','sku')"></div>来检测是否通过Validator了
以上基本是angular表单中的主要功能,下面,我们还可以监听表单的变化:
同样,对于FormControl和FormGroup,都具有一个EventEmitter用来监听变动事件的。
我们通过调用control.valueChanges来获得他们的EventEmitter:
this.sku.valueChanges.subscribe(
	(value: string) => {
		console.log("sku value changed",value)
	}
)
this.myForm.valueChanges.subscribe(
	(form: any) => {
		console.log("form chnged to:",form)
	}
)


OK,以上就是几个比较关键的ng2表单知识点。祝大家学习愉快,工作顺利。

angular2 之 form表单的更多相关文章

  1. HTML5新增form控件和表单属性实例代码详解

    这篇文章主要介绍了HTML5新增form控件和表单属性实例代码详解,需要的朋友可以参考下

  2. wordpress添加Html5的表单验证required方法小结

    这篇文章主要介绍了wordpress添加Html5的表单验证required方法小结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5表单验证特性(知识点小结)

    这篇文章主要介绍了HTML5表单验证特性的一些知识点,本文通过实例代码截图的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. amazeui页面分析之登录页面的示例代码

    这篇文章主要介绍了amazeui页面分析之登录页面的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. ios – Swift Eureka Form中的循环

    我正在构建一个Eureka表单,并希望在表单中放置一个循环来构建基于数组的步进器列表.我试图使用的代码是:但是,当我这样做时,我在StepperRow行上出现了一个错误:所以看起来Swift不再认为它在形式之内并且正在关注

  6. swift 上传图片和参数 upload image with params

    Alamofire.upload(urlRequest.0,urlRequest.1).progress{(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite)inprintln("\(totalBytesWritten)/\(totalBytesExpectedToWrite)")}}

  7. swift – 使用PostgreSQL在Vapor 3中上传图片

    我正在关注这些家伙MartinLasek教程,现在我正在“图片上传”.似乎没有人能回答“如何上传iVapor3图像”的问题Db连接正常,所有其他值都保存.这是我的创建方法:和型号:}和叶子模板:我知道需要一种管理文件的方法和原始图像字节,但我怎么去那里?这使用多部分表单的自动解码:upload.leaf文件是:使用File类型可以访问上载文件的本地文件名以及文件数据.如果将其余的Question字段添加到ExampleUpload结构中,则可以使用该路径捕获整个表单的字段.

  8. android – 有没有办法阻止Mobile Safari在HTML表单的数字字段中插入逗号?

    我有一个网站,其中包含一个表单,允许用户输入信用卡详细信息.卡号,发行号,CVC号和他们希望存入的金额的字段使用HTML形式的输入框,类型为“数字”.iOS5附带的更新的MobileSafari会自动在“数字”输入字段中将逗号插入数字中.这不仅在CC编号中看起来很愚蠢,而且会破坏我的验证.有办法阻止这个吗?

  9. Angular2 PrimeNG分页模块学习

    这篇文章主要为大家详细介绍了Angular2 PrimeNG分页模块学习教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. jquery validate表单验证的基本用法入门

    这篇文章主要为大家介绍了jquery validate表单验证的基本用法入门,jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求,感兴趣的小伙伴们可以参考一下

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部