一、响应式表单定义
响应式表单:我们在组件中创建表单控件的对象树,并使用特定的方式将绑定到组件模板中的原声表单控件元素上
二、响应式表单的好处
我们可以在组件类中直接创建和维护表单控件对象。由于组件类可以同时访问数据模型和表单控件结构, 因此我们可以把表单模型值的变化推送到表单控件中,并把变化后的值拉取回来。 组件可以监听表单控件状态的变化,并对此做出响应
三、响应式表单中涉及到的词汇及含义
词汇 | 解释 | 使用场景 |
---|---|---|
formControl | 用户跟踪一个单独表单控件的值和有效性状态 | |
formGroup | 用户跟踪一组表单控件的值和有效性状态 | |
FormArray | 有序数组的值和有效性 |
四、formControl
简单的使用
public name1 = new FormControl(初始值,验证器数组,一部验证器数组)
<input type="text" class="form-control" [formControl]="name1">
五、formGroup
的使用
public formgroup = new FormGroup({
name:new FormControl("你好"),
password:new FormControl("",Validators.required)
})
在html页面中可以通过:
* 1、formgroup.value
获取表单中全部的值
* 2、formgroup.status
检验表单当前是处于什么状态
<form role="form" [formGroup]="formgroup" novalidate>
<div class="form-group">
<label>用户名:</label>
<input type="text" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<label>密码:</label>
<input type="password" class="form-control" formControlName="password" />
</div>
</form>
<p>Form value: {{ formgroup.value | json }}</p>
<p>Form status: {{ formgroup.status | json }}</p>
六、与FormBuilder
结合使用,官方解释
修改组件代码
...
constructor(private fb : FormBuilder) {
this.createForm();
}
public formgroup : FormGroup;
createForm() {
this.formgroup = this.fb.group({
name: new FormControl("你好"), //下面几种方式也可以
password: ["",Validators.required],
city:''
})
}
....
七、多个FormGroup
的使用
项目中表单越来越复杂,那么就可以使用多个
FormGroup
来区分使用
<fieldset formGroupName="password">
<div class="form-group">
<label>密码:</label>
<input type="password" class="form-control" formControlName="first" />
</div>
<div class="form-group">
<label>确认密码:</label>
<input type="password" class="form-control" formControlName="last" />
</div>
</fieldset>
createForm() {
this.formgroup = this.fb.group({
name: new FormControl("你好"),
password: this.fb.group({
first:'',
last:''
}),
city:'',
state:'',
sex:["",Validators.required],
hobby:''
})
}
八、获取FromControl
的属性
属性 | 说明 |
---|---|
value | FormControl 的值。 |
status | FormControl 的有效性。可能的值有VALID、INVALID、PENDING 或DISABLED 。 |
pristine | 如果用户尚未改变过这个控件的值,则为true 。它总是与myControl.dirty 相反。 |
untouched | 如果用户尚未进入这个HTML 控件,也没有触发过它的blur (失去焦点)事件,则为true。 它是myControl.touched 的反义词。 |
使用方式
<input type="text" class="form-control" [formControl]="name1">
<div>{{name1.value}}</div>
<div>{{name1.status}}</div>
<div>{{name1.pristine}}</div>
<div>{{name1.untouched}}</div>
<input type="text" class="form-control" formControlName="city" />
<p>{{formgroup.get("city").value}}</p>
九、关于赋值、修改、提取
1、给
form
表单里面的formControl
赋值- 前面就提到了,直接在创建的时候赋值就可以传递到
html
页面 - 使用
setValue
(尝试失败,直接使用patchValue
)
- 前面就提到了,直接在创建的时候赋值就可以传递到
2、修改值使用
patchValue
//修改值 edit(){ this.formgroup.patchValue({ name:"我不是很好" }) }
3、提取表单值
<form role="form" [formGroup]="formgroup" novalidate (ngSubmit)="postData()"> .... </form>
//提交数据 postData(){ console.log(this.formgroup.value); }
十、表单的校验
1、使用自带的校验器
Validators.required
必填字段Validators.minLength
最小长度Validators.maxLength
最大长度username:["",[Validators.required,Validators.minLength(3),Validators.maxLength(6)]],
<!--还没封住指令--> <div class="form-group"> <label>用户名:</label> <input type="text" [class]="!myform.get('username').untouched?(myform.get('username').status==='VALID'?'form-control':'form-control error'):'form-control'" formControlName="username"> <!--如果没有访问的时候或者不含有required的时候隐藏--> <p [hidden]="myform.get('username').untouched || !myform.hasError('required','username')" class="text-danger">用户名必填</p> <p [hidden]="myform.get('username').untouched || (!myform.hasError('minlength','username') ? !myform.hasError('maxlength','username'):null)" class="text-danger">用户名长度有误</p> </div>
2、自定义校验器
直接定义在组件内
//定义一个手机号码的校验器 mobileValidator(control:FormControl):any{ var reg = /^1[34578]\d{9}$/; let valid = reg.test(control.value); //如果验证通过就返回null否则就返回手机号码格式有误 return valid ? null:{moblie:"手机号码格式有误"}; } //使用 mobile_num:["",[Validators.required,this.mobileValidator]],
- 定义一个服务注入到组件中(自行看代码实现)