如何订阅嵌套Observable数组并返回触发变更的根对象
问题描述
现有如下对象数组,每个对象包含def标识属性和value属性,其中value为Observable类型(示例中为EventEmitter实例):
let myArray = [{def: 'name1', value: EventEmitter_}, {def: 'name2', value: EventEmitter_}]
需求:订阅数组内所有Observable,当任意Observable发出值触发变更时,返回该Observable所属的根对象。
已尝试的无效方案
- 方案1:遍历数组逐个订阅value属性
myArray.forEach(e => { e.value.subscribe(e => console.log(e)) })
缺陷:订阅回调中只能获取到Observable发出的具体值,无法拿到对应的根对象。
- 方案2:直接使用merge操作符合并原数组
merge(myArray).subscribe((v)=> { console.log(v) })
缺陷:merge接收的参数应为Observable序列,直接传入普通对象数组无法处理嵌套的Observable属性,达不到预期效果。
实现方案
核心思路是先对每个对象的value Observable做转换,通过map操作符将其发出的任意值映射为所属的根对象,再将所有转换后的Observable传入merge合并即可。
import { merge, map } from 'rxjs'; // 遍历数组,将每个对象的value Observable转换为发值时返回根对象的新Observable const observableList = myArray.map(item => { return item.value.pipe( // 忽略原始发出值,直接返回所属根对象 map(() => item) ); }); // 合并所有转换后的Observable,任意源触发都会推送对应的根对象 merge(...observableList).subscribe(targetItem => { console.log('触发变更的对象为:', targetItem); // 可直接访问targetItem.def、targetItem.value等属性 });
如果需要同时拿到Observable发出的原始值和根对象,调整map的返回值即可:
map(emitValue => ({ currentItem: item, emitValue: emitValue }))
内容的提问来源于stack exchange,提问作者seeman
相关产品推荐
相关产品推荐

