Angular中极好的一点就是表单,使用ReactiveForms可以方便快捷的进行表单验证。
最近遇到一个bug,会员卡请假,可填写请假天数(days)或设置假期截止日期(endAt),但只有一个可编辑,另一个为disabled状态,并且days改变自动计算endAt,设置endAt自动计算days。
定义一个表单:
import {FormBuilder, FormGroup, Validators} from '@angular/forms'
constructor(private fb: FormBuilder) {
this.daysForm = fb.group({
days: ['', Validators.compose([Validators.required, aliValidators.number])],
endAt: ['', Validators.required],
remark: [''],
daysType: ['numb'], // 输入天数 or 选择日期
})
}
提交表单时需要取出表单中的数据,一般来说,this.daysForm.value
和this.daysForm.getRawValue()
均可,并且取出的值是相同的。
但某次此功能通过设置endAt,并自动计算days提交时,使用this.daysForm.value
,无论如何都取不出value中的days值,界面显示正确
值取不到
debug时发现daysForm这个FormGroup的value属性中确实无days这个字段
后来尝试使用this.daysForm.getRawValue()
取值,取到了正确的days,且days FormControl的status = 'DISABLED'
,但是value = 16
存储正确
由此可见,
- 当一个FormControl(days)为禁用状态且手动改变它的值时
this.daysForm.patchValue({days: 16})
,改变的仅仅是此FormControl的value,并不能改变FormGroup(daysForm)的value中days的值。 this.daysForm.value
取得是FormGroup(daysForm)的value属性,返回一个对象;
this.daysForm.getRawValue()
会遍历FormGroup(daysForm)的controls属性,返回每一个FormControl中的value;即
const value = {}, {controls} = this.daysForm
for (const key in controls) {
if (key) {
value[key] = controls[key].value
}
}
this.daysForm.getRawValue() = value // object中的值相等