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中的值相等