Rxjs 将动态数组的动态数组转换为可观察的

Rxjs 将动态数组的动态数组转换为可观察的,rxjs,reactivex,Rxjs,Reactivex,我有一个动态数组结构。具体来说,就是谷歌地图。此结构具有常规的put、get和remove方法,以及一个addListener来侦听任何更改。库方法(Polygon#getpath)返回一个MVCArray of MVCArray of LatLngs,因为多边形可以有任意数量的路径,而每条路径可以有任意数量的顶点 我的目标是转换生成一个可观察的PolygonPathEvent,当父MVCArray或子MVCArray发生更改时,该事件将触发 创建可观察对象 第一个任务是将addListener

我有一个动态数组结构。具体来说,就是谷歌地图。此结构具有常规的put、get和remove方法,以及一个
addListener
来侦听任何更改。库方法(Polygon#getpath)返回一个MVCArray of MVCArray of LatLngs,因为多边形可以有任意数量的路径,而每条路径可以有任意数量的顶点

我的目标是转换生成一个可观察的
PolygonPathEvent
,当父MVCArray或子MVCArray发生更改时,该事件将触发

创建可观察对象 第一个任务是将
addListener
转换为可观察对象

private createMVCEventObservable<T>(array: MVCArray<T>): Observable<[T[], string, number, T?]>{
    const eventNames = ['insert_at', 'remove_at', 'set_at'];
    return fromEventPattern(
      (handler: Function) => eventNames.map(evName => array.addListener(evName,
        (index: number, previous?: LatLng) => this._zone.run(() => handler.apply(array, [[array.getArray(), evName, index, previous]])))),
      (handler: Function, evListeners: MapsEventListener[]) => evListeners.forEach(evListener => evListener.remove()));
  }
问题是MVCArray的父MVCArray可以更改,但是
CombineTest
接受一个静态数组。因此,当添加了一条新路径时,我不知道如何使返回的可观察对象也侦听这个新路径。同样,如果一个路径被删除,我不知道如何使返回的可观察的取消订阅从删除的路径

管道至主体(错误方法) 我考虑返回一个主题,只要在父对象发生变化时将其订阅到不同的可观察对象

const retVal: Subject<PolygonPathEvent> = new Subject();
const pathsChanges$ = this.createMVCEventObservable(paths);
const pathChanges$ = combineLatest(paths.getArray().map(this.createMVCEventObservable));
let latestSubscription = combineLatest(pathChanges$, pathsChanges$, (pathArr, paths) => 
  new PolygonPathEvent(pathArr, paths)
).subscribe(retVal);

pathsChanges$.pipe(tap( ([arrays, event, index, previous]) => {
  latestSubscription.unsubscribe();
  latestSubscription = combineLatest(pathChanges$, pathsChanges$, (pathArr, paths) => 
  new PolygonPathEvent(pathArr, paths)
  ).subscribe(retVal);
} ));

return retVal;
const retVal:Subject=new Subject();
const pathsChanges$=this.createMVCEventObservable(路径);
const pathChanges$=CombineTest(path.getArray().map(this.createMVCEventObservable));
让latestSubscription=CombineTest(pathChanges$,pathsChanges$,(pathArr,paths)=>
新PolygonPathEvent(路径,路径)
).认购(退还);
pathsChanges$.pipe(点击([Array,event,index,previous])=>{
最新订阅。取消订阅();
latestSubscription=CombineTest(pathChanges$,pathsChanges$,(pathArr,paths)=>
新PolygonPathEvent(路径,路径)
).认购(退还);
} ));
返回返回;
这是可行的,问题是,在这个方法中,对原始可观察对象(和addListener)的订阅是正确的,而不是在订阅返回的可观察对象时

结论
我需要某种操作符来解决这个问题。

如果我正确理解您的问题,可能会有空间使用
开关映射来解决它

您说“问题是MVCArray的父MVCArray可以更改,但是CombineTest接受静态数组”。我认为您引用的静态数组是由
pathChanges$
Observable发出的,它在代码片段的开头一次性创建,当MVCArray的父MVCArray更改时不会更新

如果我的理解是正确的,我们需要做的是提供一种方法来通知MVCArray的父MVCArray的更改事件,并且在任何时候发生此类事件时,使用新更新的数组再次执行
combineLatest
函数

这可以通过以下类似的逻辑实现

const pathsChanges$ = this.createMVCEventObservable(paths);

pathsChanges$
.pipe(
   switchMap(() => combineLatest(paths.getArray().map(this.createMVCEventObservable))),
   map(pathArr => new PolygonPathEvent(pathArr, paths))
)
此逻辑假定变量
路径
从外部传入此逻辑段


我无法重现该案例,因此我无法确定我的答案是否能解决您的问题,即使我希望它能有所帮助。

您是否尝试过操作员?您可以订阅其中的更改并返回主题。仔细查看,但这不是正确的解决方案。目前正在考虑自定义运算符。
const pathsChanges$ = this.createMVCEventObservable(paths);

pathsChanges$
.pipe(
   switchMap(() => combineLatest(paths.getArray().map(this.createMVCEventObservable))),
   map(pathArr => new PolygonPathEvent(pathArr, paths))
)