表单控件 valueChanges 给出之前的值
Form control valueChanges gives the previous value
我在表单对象 parentForm
中有一个名为 'question1'
的表单控件,我已经通过以下方式订阅了它。
它是一个单选按钮,有两个选项 Yes
和 No
,当我 select No
我得到 Yes
当我 select Yes
是 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']
它会给出以前的值。
我试图在从 this.parentForm.value['question1']
检索值之前放置一个 setTimeout()
,它工作正常。
setTimeout(() => {
console.log(this.parentForm.value['question1']); // gives the correct value.
}, 500);
但我的问题是为什么 parentForm
在其控件的值更改时没有更新,而且我也是在值更改后才检索它的值。
注意:我不想观察 parentForm.valueChanges
,这不是我的要求。
valueChanges
事件被触发在新值更新为FormControl
值之后,在[=22=之前] ] 更改冒泡到其父级和祖先级。因此,您将必须访问 FormControl
本身的值(刚刚被修补),而不是 FormGroup
值对象的字段(在事件期间未被触及)。
鉴于此,请改用 this.parentForm.get('question1').value
:
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.get('question1').value);
}
);
还有一种选择,但它可能并不适合所有情况:您可以等待 one tick 在 FormControl 中更新 selectedValue
之前:
setTimeout( () => console.log( selectedValue ) );
有关 sync/async 表单主题的更多信息:Reactive forms 在 Angular 指南文档中。
尝试这样做
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.value.question1);
}
);
如果更新了 FormBuilder 的控件,您可以立即通过 属性 值
从 FormBuilder 对象恢复最后的值
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
更新
如果您注意到 startWith
似乎已弃用,但事实并非如此。操作员只有一个活动签名,您可以在 .
中阅读相关信息
Highly likely, you are using startWith(null) or startWith(undefined), they are not deprecated despite the notice, but IDE detects a wrong function signature, which is deprecated, and shows the warning.
一个简单的解决方法是提供预期的 return 类型:
// Prevent deprecation notice when using `startWith` since it has not been deprecated
this.form.get('fieldName')
.valueChanges
.pipe(startWith(null as string), pairwise())
.subscribe(([prev, next]: [any, any]) => ... );
它在 StackBlitz 中与 startWith
一起工作的示例:
https://stackblitz.com/edit/angular-reactive-forms-rvxiua
我在表单对象 parentForm
中有一个名为 'question1'
的表单控件,我已经通过以下方式订阅了它。
它是一个单选按钮,有两个选项 Yes
和 No
,当我 select No
我得到 Yes
当我 select Yes
是 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']
它会给出以前的值。
我试图在从 this.parentForm.value['question1']
检索值之前放置一个 setTimeout()
,它工作正常。
setTimeout(() => {
console.log(this.parentForm.value['question1']); // gives the correct value.
}, 500);
但我的问题是为什么 parentForm
在其控件的值更改时没有更新,而且我也是在值更改后才检索它的值。
注意:我不想观察 parentForm.valueChanges
,这不是我的要求。
valueChanges
事件被触发在新值更新为FormControl
值之后,在[=22=之前] ] 更改冒泡到其父级和祖先级。因此,您将必须访问 FormControl
本身的值(刚刚被修补),而不是 FormGroup
值对象的字段(在事件期间未被触及)。
鉴于此,请改用 this.parentForm.get('question1').value
:
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.get('question1').value);
}
);
还有一种选择,但它可能并不适合所有情况:您可以等待 one tick 在 FormControl 中更新 selectedValue
之前:
setTimeout( () => console.log( selectedValue ) );
有关 sync/async 表单主题的更多信息:Reactive forms 在 Angular 指南文档中。
尝试这样做
this.parentForm.controls['question1'].valueChanges.subscribe(
(selectedValue) => {
console.log(selectedValue);
console.log(this.parentForm.value.question1);
}
);
如果更新了 FormBuilder 的控件,您可以立即通过 属性 值
从 FormBuilder 对象恢复最后的值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
更新
如果您注意到 startWith
似乎已弃用,但事实并非如此。操作员只有一个活动签名,您可以在
Highly likely, you are using startWith(null) or startWith(undefined), they are not deprecated despite the notice, but IDE detects a wrong function signature, which is deprecated, and shows the warning.
一个简单的解决方法是提供预期的 return 类型:
// Prevent deprecation notice when using `startWith` since it has not been deprecated
this.form.get('fieldName')
.valueChanges
.pipe(startWith(null as string), pairwise())
.subscribe(([prev, next]: [any, any]) => ... );
它在 StackBlitz 中与 startWith
一起工作的示例:
https://stackblitz.com/edit/angular-reactive-forms-rvxiua