Angular4——7.表单处理
在Angular中存在两种表单处理方式:
模版驱动式表单
表单的数据模型是通过组件模版中的相关指令来定义的。由于使用这种方式定义表单的数据模型时,我们会受限于HTML的语法,所以,模版驱动方式只适用于一些简单的场景。
响应式表单
使用响应式表单时,通过编写TypeScript代码而不是Html代码来创建一个底层的数据模型,在定义好这个模型以后,使用一些特定的指令,将模版上的HTML元素与底层的数据模型连接在一起。
Angular表单API
不管是哪种表单,都有一个对应的数据模型来存储表单的数据。在模版式表单中,数据模型是由angular基于组件模版中的指令隐式创建的。而在响应式表单中,你通过编码明确的创建数据模型然后将模版上的html元素与底层的数据模型连接起来。
数据模型并不是一个任意的对象,它是一个由angular/forms模块中的一些特定的类,如FormControl,FormGroup,FormArray等组成的。在模版式表单中,是不能直接访问这些类的。
响应式表单并不会替你生成HTML,模版仍然需要你自己来编写。
模版式表单
使用模版式表单时,需要引入FormsModule,只能使用指令定义数据模型。这些指令都来自于FormsModule模块。
|
|
##模版式表单的指令:
NgForm
ngForm指令代表整个表单,在Angular应用里ngForm指令会自动的添加到每一个<form>表单上。ngForm会隐式的创建一个FormGroup类的实例,这个类用来代表表单的数据模型,并且存储表单的数据。
|
|
Angular应用会自动为
<form>元素添加ngForm指令。ngForm会自动拦截表单的提交事件,阻止表单的提交。Angular用一个自定义的ngSubmit事件来代替他。1234<form (ngSubmit)="test()"><div>昵称:<input type="text"></div><button type="submit">提交</button></form>ngForm会自动发现添加了ngModel的子元素,并将这些子元素的值会被添加到表单数据模型中。ngForm指令可以也可以在其他元素上使用,比如<div ngForm>,这和写一个<form>效果是一样的。如果你不希望Angular来自动处理你的表单,你可以在
<form>元素上明确的添加ngNoForm指令:1<form ngNoForm>...</form>添加了
ngNoForm指令,angular将不再接管<form>表单的处理。ngForm指令创建的对象可以被一个模版本地变量引用,以便在模版中访问ngForm对象的实例。value是一个JS对象,保存着form表单中所有字段的值。
1234567<form #myForm="ngForm"><div>昵称:<input ngModel name="nickName" type="text"></div></form><div>{{myForm.value}}</div>//昵称:Tom//{nickName: Tom}
###NgModel
ngModel指令代表表单中的一个字段,ngModel指令会隐式的创建一个FormControl类的实例,来代表字段的数据模型,并用这个FormControl的对象来存储字段的值。
|
|
在
<form>标签或者标记了ngForm指令的HTML元素内,使用ngModel指令时,不需要像双向绑定那样用[()]扩起来,应为这里不是双向绑定,而是表单字段的指令;也不需要绑定到组件的属性上。但是
ngModel指令需要为添加它的HTML元素指定name的值。如果不指定name属性的值,angular不知道以什么名字把这个字段的值添加到数据模型中。与
ngForm类似,ngModel指令创建的对象也可以被模版本地变量引用,并通过模版本地变量来访问这个对象的值。12345<form #myForm="ngForm"><div>昵称:<input #myNickName="ngModel" ngModel name="nickName" type="text"></div></form><div>{{myForm.value}}</div><div>昵称的值是:{{myNickName.value}}</div>
###NgModelGroup
ngModelGroup指令代表表单的一部分,他将表单的一部分组织在一起,形成更清晰的层级关系。
与ngForm类似,ngModelGroup也会创建一个FormGroup类型的对象。
|
|
#响应式表单
创建响应式表单与模版式表单不同,需要两步:
- 首先通过编码创建一个数据模型。
- 然后使用指令将模版中的HTML元素连接到数据模型上。
使用响应式表单时,需要引入ReactiveFormsModule模块,响应式表单的指令都来自ReactiveFormsModule模块。
|
|
数据模型
数据模型是指一个用来保存表单数据的数据结构,他由定义在FormsModule模块中的三个类组成:
FormControl:
他是构成表单的基本单位,通常情况下用来表示一个
<input>元素,也可以用来表示更复杂的UI组件。FormControl类的对象保存着与其关联的HTML元素当前的值,元素是否被修改过,以及校验状态等信息。
12// ReactiveForm.component.tsprivate nickname = new FormControl('tom');FormControl接收的参数用来制定初始值。模版式表单中,
ngModel指令默认会为其附着的元素创建一个FormControl类的对象。
FormGroup:
FormGroup类代表表单的一部分,也可以表示整个表单,他是多个FormControl的集合。FormGroup将多个FormControl的状态和值聚合在一起。如果其中一个FormControl的值是无效的,也就是不符合校验规则,那么整个FormGroup都是无效的。12345// ReactiveForm.component.tsprivate passwordInfo = new FormGroup({password: new FormControl(),passwordConfirm: new FormControl()})FormGroup的构造函数需要传入一个对象{},这个对象里是FormControl。
FormArray:
FormArray和FormGroup是类似的,但是有一个额外的属性,长度,因为FormArray是一个数组。FormGroup用来代表整个表单,或者一个表单中固定的子集。FormArray用来代表一个可以增长的集合。比如,一个表单中的邮箱字段,一个用户可以拥有多个邮箱。123456// ReactiveForm.component.tsprivate emails = new FormArray([new FormControl(),new FormControl(),new FormControl()])FormArray中的FormControl没有key,而FormGroup中的FormControl是要有一个key。
编写一个完整的表单数据模型:
|
|
##响应式表单的指令:
在控制器中已经构建好了数据模型,在模版中通过指令,将表单元素和数据模型连接起来。
响应式表单使用和模版式表单完全不同的指令,这些指令来自于ReactiveFormsModule模块。
响应式表单的指令分成两种,一种是需要使用属性绑定语法[xxx]="xxx"的指令,另一种是不需要属性绑定语法的指令。
响应式表单的所有指令,都是以form开头的;而模版式表单的所有指令,都是以ng开头的。
###使用属性绑定的指令:
formGroup,formControl
这种指令使用时必须使用属性绑定语法,就是说使用这些指令时,需要使用属性绑定的语法,用[]扩起来。
属性绑定的指令,必须绑定到组件中的某个属性上,比如:
|
|
指令的名字很简单,和类名一样,首字母小写。
FormArray类没有属性绑定方式的指令,因为它是数组,没有key来对应。
###不使用属性绑定的指令:
formGroupName,formControlName,formArrayName
这些以Name结尾的指令可以使用属性的名字来连接DOM元素和数据模型,它们不需要使用属性绑定语法。
formGroup通过属性绑定将表单绑定到组件中的formModel属性上,nickname不是组件的属性,只是数据模型中的一个字段的key,因此不能用属性绑定[formControl]="nickname",否则会报错。
|
|
与模版式表单不同,响应式表单的指令都是不可引用的,不能像模版式表单那样用模版本地变量来引用。
而在模版式表单中,不能在控制器中直接访问FormGroup、FormControl这些类。
Angular是故意这么做,目的就是区分模版式表单和响应式表单。
|
|
|
|
注意:
- 处理submit事件:
- 模版式表单中提供了
ngSubmit事件来处理表单提交:<form #myForm="ngForm"(ngSubmit)="createUser(myForm)"。在模版式表单中,通过把保存表单数据的模版本地变量传给控制器来获取表单数据。 - 响应式表单中直接处理原生的
submit事件:<form (submit)="createUser()">。并且,不需要传模版本地变量,因为响应式表单中本身就不能引用模版本地变量,表单的数据模型是在组件控制器中定义的,在控制器中就能直接拿到数据。
- 模版式表单中提供了
FormBuilder
FormBuilder是Angular提供的一个工具类,它并没有提供新的功能,只是简化构建响应式表单数据结构的语法。
|
|
new FormGroup({}) = new FormBuilder().group({});new FormControl() = new FormBuilder().[''];new FormArray([]) = new FormBuilder().array([]);
此外,FormBuilder还可以对表单模型进行其他的配置,比如校验表单。
表单校验
Angular校验器
angular校验器有两种,一个是自己定义的校验器,另一个是angular预定义好的校验器:
Angular预定义的校验器
angular提供的校验器都在一个叫Validators的类中,这个类有很多方法,比如:
Validators.required必填的校验器Validators.minLength()最小长度的校验器Validators.maxLength()最到长度的校验器
等等。
当有了定义好的校验器,包括angular提供的或者自己定义的,我们就可以配置数据模型来使用校验器。
将校验器作为参数传到表单模型的构造函数中就能进行校验:
|
|
这个意思是nickname这个字段是必填的。
也可以同时传入多个校验器,那么这个参数就是一个数组:
|
|
nickname这个字段是必填的,同时最小长度是5。
###自定义校验器
自定义的校验器实际上就是一个自定义的方法,该方法要求需要传入一个AbstractControl类的参数,并且该方法的返回值必须是key为string类型的对象:
|
|
AbstractControl类是FormGroup,FormControl,FormArray的父类,因此,自定义校验器的参数可以是这三个类中的任意一种。
当需要更复杂的校验规则时,angular提供的校验器可能无法满足需求,我们可以通过自定义的检验器来实现。
响应式表单校验
|
|
|
|
|
|
|
|
FormGroup.hasError('校验器的key','被校验字段的key')FormGroup.getError('校验器的key','被校验字段的key')FormGroup.get('').
Angular4——7.表单处理的更多相关文章
- Angular4笔记——表单状态相关的属性
表单状态字段(FromControl)touched和untouched用来判断用户是否访问过一个字段(也就是这个字段是否获取过焦点,如果获取过焦点,touched是true,untouched是fa ...
- angular4 form表单验证
<!-- novalidate 清除浏览器默认的校验行为 --> <form [formGroup]="formModel" (ngSubmit)="o ...
- angular4 自定义表单验证Validator
表单的验证条件有时候满足不了需求就可以自定义验证 唯一要求返回是ValidatorFn export interface ValidatorFn{ (c:AbstractControl):Valida ...
- angular4 自定义表单组件
自定义表单组件分为单值组件和多值组件. 单值组件:input/select/radio/textarea 多值组件:checkbox/tree组件 条件: 1.必须实现ControlValueAcce ...
- angular4 Form表单相关
ng4中,有两种方式去声明一个表单 一:Template-Driven Forms - 模板驱动式表单 [引入FormsModule] 1.ngForm赋值 [可以方便的获取表单的值] <f ...
- Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定
Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定 创建 angular 组件 https://github.com/angular/angular- ...
- Angular2 表单验证相关
angular4响应式表单与校验http://blog.csdn.net/xiagh/article/details/78360845?locationNum=10&fps=1 How to ...
- angularcli 第五篇(输入框、表单处理)
本文参考:Angular4 表单快速入门 注:涉及input表单时要在AppComponent中引入 FormsModule模块: import{ FormsModule } from '@a ...
- ASP.NET Aries 入门开发教程9:业务表单的开发
前言: 经过前面那么多篇的列表的介绍,终于到了大伙期待的表单开发了. 也是本系列的最后一篇文章了! 1:表单页面的权限设置与继承 对于表单页面,权限的设置有两种: 1:你可以选择添加菜单(设置为不显示 ...
随机推荐
- 计量经济与时间序列_滞后算子和超前算子L的定义
1. 为了使计算简单,引入滞后算子的概念: 2. 定义LYt = Yt-1 , L2Yt = Yt-2,... , LsYt = Yt-s. 3. 也就是把每一期具体滞后哪一期的k提到L的 ...
- 计算文本长度-boundingRectWithSize
- (void)viewDidLoad { [super viewDidLoad]; //新建lable控件 UILabel *lable=[[UILabel alloc]init]; labl ...
- 关于前端JS的总结
简介 JavaScript是一种计算机编程语言,可以像等其他编程语言那样定义变量,执行循环等.主要执行在浏览器上,为HTML页面提供动态效果,而且JavaScript是一种脚本语言,它的代码是解释执行 ...
- 关于 Xpath 定位
关于 Xpath 定位 问: // 和 / 的区别 表达式 描述 nodename 选取此节点的所有子节点. / 从根节点选取. // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置. . ...
- 方格取数(多线程dp,深搜)
https://www.luogu.org/problem/P1004 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某 ...
- mysql,主键与索引的区别和联系
关系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成 ...
- mysql常用方法案例
SELECTms.id,ms.name,ms.address,ms.mobile AS phone,ms.UUID,(case when ce.score is null then 0 else ce ...
- php mb_substr()函数的详细解释!
PHP substr()函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函数,mb_substr() /mb_strcut的用法 ...
- jmeter测试get post 笔记
0 环境 系统环境:win7 1 操作 1 post 新建线程组 2 get 和post新建类似 http请求 只是新建一个参数化我测试的2个url http://127.0.0.1:8080/cry ...
- 批量修改ACCESS表列名
问题来源:从ODBC导入数据到ACCESS 再从ACCESS导入到SQL数据库,ACCESS会多带个DBO. 所以需要批量修改ACCESS的表名. 首先需要引用ADOX引用方法:打开ACCESS的VB ...