Angular 表单介绍
表单中的重要概念
1: FormControl:表单控件,封装了表单中的输入,并提供了一些可供操纵的对象
2: Validator:验证器,对表单的输入根据自己的需要添加一些限制
3: Observer:观察者,监听表单的变化,并作出相应的回应
两个基础的表单对象
FormControl:单一的输入字段,封装了字段的值和状态,提供了一系列的公共API;获取value时,会收到一个“键值对”结构的对象。
FormGroup:为一组FormControl提供总包接口管理多个FormControl,也提供了一系列公共的API。
FormControl和FormGroup都继承自同一个祖先AbstractControl。
两种表单
Template Driven Forms:模板驱动式表单
Reactive Forms:响应式表单
Angular中支持的内建validators有:
required:设置表单控件值是非空的
-
email:设置表单控件值的格式时email
-
minlength:设置表单控件值的最小长度
-
maxlength:设置表单控件值的最大长度
-
pattern:设置表单控件的值需匹配pattern对应的模式
通过对象的errors属性来获取对应验证规则的验证状态。
表单控件的六种状态:
- valid - 表单控件有效
- invalid
- pristine - 表单控件值未改变
- dirty - 表单控件值已改变
- touched - 表单控件已被访问过
- untouched - 表单控件未被访问
Template Driven Forms(模板驱动式表单)
-
绑定ngForm
<form novalidate #f="ngForm">
<label>
<span>Your name</span>
<input type="text" placeholder="Please input your name">
</label>
</form>
把ngForm的值赋给#f变量,访问该变量可以方便的获取该表单的值。#f变量的值,是ngForm指令的导出对象。
-
三种数据绑定方式:ngModel、[ngModel]、[(ngModel)]
-
ngModel
-
直接使用该指令,没有使用绑定或关联任何值,这时,ngModel将自动关联表单控件的name属性,并将该值作为ngForm对象的属性名;若input输入框未设置name属性,则会抛出异常。
至此,我们已经绑定了name输入框的值,下面为输入框设置初始值。
-
[ngModel]
单向数据绑定。允许我们使用this.user.name来设置name输入框的初始值,并且该值会自动绑定到f.value对象上。
但是由于是单向数据绑定,所以当表单name输入框的值改变时,不会同步更新到this.user.name。
此时,我们通过双向数据绑定来实现这一功能。
-
[(ngModel)]:双向数据绑定
用来管理多个ngModel,对表单输入内容进行分组,具体实例如下:
<div ngModelGroup="account">
<label>
<span>Email address</span>
<input type="email" placeholder="Your email address" name="email" ngModel>
</label>
<label>
<span>Confirm address</span>
<input type="email" placeholder="Confirm your email address" name="confirm" ngModel>
</label>
</div>
表单中提供了ngSubmit输出属性,用于监听表单的提交。
<form novalidate (ngSubmit)="onSubmit(f)" #f="ngForm">
...
</form>
当提交表单的时候,会把f作为参数,调用ngSubmit关联的onSubmit()方法。
Reactive Forms(响应式表单)介绍
-
使用响应式表单,需要导入ReactiveFormsModule。
响应式表单中的指令:
formControl / formGroup / formControlName / formGroupName / formArrayName -
表单绑定
在响应式表单中,我们移除了ngModel和name=””属性。我们需要通过[formGroup]来绑定我们创建的myGroup对象。另外,我们还要使用formControlName指令,绑定我们创建的FormControl控件。 -
表单验证
FormBuild:可以理解为生产FormControl和FormGroup的工厂。一个FormBulider实例有两个方法:
fb.control(); //构造一个FormControl实例
fb.group(); //构造一个FormGroup实例
ngOnInit() { this.diseaseForm = this.fb.group ({ id: ['', [Validators.required]], ICD_10: ['', [Validators.required, Validators.maxLength(8), Validators.minLength(7), Validators.pattern(this.icdPattern)]], site: ['', [Validators.required]], department: ['', [Validators.required]], }); }
两种表单的对比 :
- 模板式表单使用方便,适用于简单的场景;通过[(ngModel)]实现数据的双向数据绑定;不易于单元测试。
- 响应式表单较为灵活,适用于复杂的场景,简化了HTML模板的代码,把验证逻辑抽离到组件类中,方便跟踪表单控件值得变化;易于单元测试。
表单是我们经常用到的一个功能,在填写表单的过程中,不乏有很多输入框的限制及校验,我们可以根据自己的需求自定义校验器,这里没有详细展开。
还有在验证部分涉及到的方法也没有详细的说明,但是项目中有所涉及。如markAsDirty()是将表单控件值标记为已改变、markAsPristine()是将表单控件值标记为未改变,这个方法主要用在表单重置时、updateValueAndValidity()是重新计算表单控件的值和验证状态等。