Величина контроля формыChanges дает предыдущее значение
У меня есть форма управления с именем 'question1'
внутри объекта формы parentForm
, и я подписался на него следующим образом.
Его переключатель с двумя параметрами Yes
и No
, когда я выбираю No
, я получаю Yes
и когда я выбираю Yes
его a No
.
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
// If option `No is selected`
console.log(selectedValue); // displays No. OK
console.log(this.parentForm.value['question1']); // displays Yes. Problem is here
}
);
selectedValue
переменная имеет правильное значение, но если я делаю console.log(this.parentForm.value['question1']
, она дает предыдущее значение.
Я попытался поставить setTimeout()
до получения значения из this.parentForm.value['question1']
, он просто отлично работает.
setTimeout(() => {
console.log(this.parentForm.value['question1']); // gives the correct value.
}, 500);
Но мой вопрос в том, почему parentForm
не обновляется, когда изменяется его управляющее значение, и что я тоже возвращаю его значение только после того, как значение было изменено.
Примечание. Я не хочу наблюдать за parentForm.valueChanges
, а не по моему требованию.
Ответы
Ответ 1
Событие valueChanges
запускается после, новое значение обновляется до значения FormControl
, а до изменение перерисовывается до его родителя и предков. Поэтому вам нужно будет получить доступ к самому самому FormControl
(который только что был исправлен), а не к полю объекта значения FormGroup
(который нетронутым во время события).
В свете этого используйте this.parentForm.get('question1').value
вместо этого:
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.get('question1').value);
}
);
Ответ 2
Есть еще один вариант, но во всех случаях он не подходит: вы можете подождать один галочку перед обновлением selectedValue
в FormControl:
setTimeout( () => console.log( selectedValue ) );
Подробнее о теме формы sync/async:
Ответ 3
valueChanges
является Observable, так что вы можете трубы pairwise
, чтобы получить предыдущие и последующие значения в подписке.
// No initial value. Will emit only after second character entered
this.form.get('fieldName')
.valueChanges
.pipe(pairwise())
.subscribe(([prev, next]: [any, any]) => ... );
// Fill buffer with initial value, and it will emit immediately on value change
this.form.get('fieldName')
.valueChanges
.pipe(startWith(null), pairwise())
.subscribe(([prev, next]: [any, any]) => ... );
Пример его работы в StackBlitz: https://stackblitz.com/edit/angular-reactive-forms-vhtxua
Ответ 4
Попробуйте сделать это
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.value.question1);
}
);
Если элементы управления FormBuilder были обновлены, вы можете немедленно восстановить последние значения из объекта FormBuilder через значение свойства