只订阅多个 FormControl(s) 一次
Posted
技术标签:
【中文标题】只订阅多个 FormControl(s) 一次【英文标题】:Subscribe multiple FormControl(s) only once 【发布时间】:2018-07-30 15:16:57 【问题描述】:我现在根据一些逻辑从一个大型 FormGroup 中过滤掉了几个 FormControl - 我想知道如何合并/组合那些选定的 FormControl 并且只有一个订阅..
我查看了 RxJS 文档和大理石图,但没有正确理解。理解所有这些并知道在我的案例中使用哪一个是非常令人困惑的:
- forkJoin
- combineLatest
- merge
- join
- zip
以下是有关该问题的更详细信息:
假设有 2 个 FormControl(即 controlA、controlB)。每当 FormControl 值发生任何变化时,我都想执行我的一些 handlerFunction
。
* 每当任何控件 valueChanges 时,它都需要执行一次我的 handlerFunction(在我的情况下,任何一个控件都会一次更改)
谢谢。
【问题讨论】:
当一个事件触发时,你想知道两个输入的值还是只知道改变的那个? 【参考方案1】:最适合您的选择是combineLatest
,它会在所有源 Observable 发出至少一个值之后发出,然后在任何源 Observable 的每次发出时发出:
Observable.combineLatest(controlA.valueChanges, controlB.valueChanges)
.subscribe(...);
最终,您可以将每个源与startWith(null)
链接起来,以确保每个源都会立即发出一个项目,并在订阅者中过滤您想要的内容。
Observable.combineLatest(
controlA.valueChanges.startWith(null),
controlB.valueChanges.startWith(null)
)
.subscribe(([val1, val2]) => ...);
顺便说一句,关于其他运营商:
zip
- 仅在所有源发出相同数量的项目时才发出
forkJoin
- 当所有源发出至少一项并完成时发出(valueChanges
永远不会发生)
merge
- 只是合并 Observables 但你不知道哪个发出了什么值
join
- 我不认为这是 RxJS 5 的一部分
【讨论】:
感谢您的回答,这对所有其他功能及其用法非常有帮助,并且是一个很好且简单的描述。仅供参考:就我而言,根据我的情况逻辑,我不需要.startWith(null)
。谢谢。干杯,
谢谢伙计,我正在尝试将来自我的商店选择的可观察剧集流和搜索值结合起来。我使用了 combineLatest 但在页面加载时没有初始搜索值。所以startWith
来救援了。请注意,您知道必须使用管道:this.searchValue.valueChanges.pipe( startWith( '' ) )
想知道为什么 forkJoin 不能与表单控件上的 valueChanges 一起使用
@KhuramNiaz forkJoin
要求所有源 Observables 发出至少一项并完成。 valueChanges
是一个永远不会完成的主题,因为这意味着它永远不会发出任何更多的项目。【参考方案2】:
对于那些不推荐使用 combineLatest 的人,请尝试将 valueChanges 可观察对象组合到一个数组中。此外,对于那些不推荐使用 startWith 的人,请尽量不要使用 null。
combineLatest([
this.typeSelected.valueChanges.pipe(startWith('')),
this.checkedFC.valueChanges.pipe(startWith(false))
]
).subscribe(([type, checked]) =>
console.log([type, checked]);
);
【讨论】:
以上是关于只订阅多个 FormControl(s) 一次的主要内容,如果未能解决你的问题,请参考以下文章
在微服务的发布/订阅模型中,每个服务类型如何只接收/消费一次消息