仅订阅多个FormControl(s)一次

nar*_*gar 8 javascript rxjs typescript angular

基于某些逻辑,我已经从一个大型FormGroup过滤掉了一些FormControl - 我想知道如何合并/组合这些选定的FormControls并且只有一个订阅..

我查看了RxJS文档和大理石图,但没有正确理解它.理解所有这些并知道哪一个用于我的案例是非常令人困惑的:

- forkJoin
- combineLatest
- merge
- join
- zip
Run Code Online (Sandbox Code Playgroud)

以下是有关该问题的更详细信息:

假设2 FormControls(即controlA,controlB).我想handlerFunction在任何FormControl值更改时执行我的一些.*每当有任何控制值改变时,它需要执行一次handlerFunction(在我的情况下,任何一个控件都会一次更改)

谢谢.

mar*_*tin 14

最好的选择是combineLatest在所有源Observable发出至少一个值然后从任何源Observable发出的每个发射后发出:

Observable.combineLatest(controlA.valueChanges, controlB.valueChanges)
  .subscribe(...);
Run Code Online (Sandbox Code Playgroud)

最终,您可以链接每个源startWith(null)以确保每个源立即发出一个项目并过滤您在订阅者中想要的内容.

Observable.combineLatest(
    controlA.valueChanges.startWith(null),
    controlB.valueChanges.startWith(null)
  )
  .subscribe(([val1, val2]) => ...);
Run Code Online (Sandbox Code Playgroud)

顺便说一下,关于其他运营商:

  • zip - 仅在所有源发出相同数量的项目时才会发出
  • forkJoin- 当所有源发出至少一个项目并完成(从未发生valueChanges)时发出
  • merge - 只是合并Observables但你不知道哪一个发出了什么值
  • join - 我认为这不是RxJS 5的一部分


小智 5

对于那些不推荐使用 combineLatest 的人,请尝试将 valueChanges 可观察对象组合到一个数组中。此外,对于那些被弃用的 startWith,尽量不要使用 null。

combineLatest([
    this.typeSelected.valueChanges.pipe(startWith('')),
    this.checkedFC.valueChanges.pipe(startWith(false))
  ]
).subscribe(([type, checked]) => {
   console.log([type, checked]);
});
Run Code Online (Sandbox Code Playgroud)