角度反应形式:valueChanges 无法按预期工作

Mas*_*r_T 4 typescript angular angular-reactive-forms angular6

我正在学习在 Angular 6 中使用反应式表单,所以如果这个问题很愚蠢,请原谅我,但这是我的问题:

我想监视反应形式中某个值的变化,因为当发生变化时,我需要运行一些逻辑来根据新值重新计算内容。所以我尝试这样做:

this.inputGroup = formBuilder.group({
  myControl: 'something'
});

this.inputGroup.get('myControl').valueChanges.subscribe(newVal => {
  console.log("new value", newVal); //Prints the correct new value
  console.log("actual value", this.inputGroup.value.myControl); //Prints the previous (old) value!

  this.someFuncThatExpectsTheValuesToBeUpToDate(); //This will find the OLD value inside this.inputGroup.value.myControl, instead of the new one!
});
Run Code Online (Sandbox Code Playgroud)

但是,正如您从我在代码中放入的注释中看到的那样,这不起作用,因为valueChanges似乎在模型中的值实际更改之前被调用!这是有意的行为吗?方法签名valueChanges表示:

每当控件的值在 UI 中或以编程方式发生变化时,都会发出一个多播可观察对象。

所以我假设它是在表单中的值更改后调用的,但显然不是......这是正确的吗?如果是这样,我如何检测控件中的值何时实际发生变化?

编辑:对于为什么我希望我的函数直接从 Form 组访问数据,而不是将新值传递给函数本身,似乎存在一些困惑(一如既往,SO :D)。这很容易解释:该函数从多个表单组收集数据并使用这些数据进行一些辅助计算。通过直接从表单组访问数据,该函数是通用的,可以从任何地方调用。如果我开始在那里放置输入参数,这就会中断。举个例子:

someFuncThatExpectsTheValuesToBeUpToDate(){
  let val1 = inputGroup.value.myControl;
  let val2 = someOtherFormGroup.value.myOtherControl;
  let val3 = yetAnotherFormGroup.value.someOtherControl;
  //do something with the vals
}
Run Code Online (Sandbox Code Playgroud)

有了这个函数,我可以从任何地方调用它并且它会起作用。但如果我每次都需要传入值,我将需要 3 个具有不同签名的不同函数来完成相同的操作,更加混乱和复杂。

Fra*_*ous 5

valueChanges在新值更新为 FormControl 值之后、更改向上冒泡到其父级和祖先之前,会触发该事件。因此,您必须访问 FormControl 本身的值,而不是 FormGroup 值对象的字段。

订阅内的console.log this.inputGroup.get('myControl').value它将具有新值。

  • 谢谢富兰克林,这是正确的答案!我对角度很陌生,显然我没有正确理解两者之间的区别。如果我理解正确的话:我正在访问 FormGroup 中设置的值(基本上:用于生成/填充控件的值),而不是访问控件本身中的当前数据。我对么? (2认同)
  • @Master_T 最初,表单控件值被更新,然后它被冒泡到父级并更新表单和值。并且您正在尝试访问尚未更新的表单(父级)的值。 (2认同)
  • 感谢您的解释,非常感谢 (2认同)