У меня есть структура динамического массива.В частности, это Google Maps ' MVCArray .Эта структура имеет обычные методы put, get, remove, а также addListener
для прослушивания любых изменений.Библиотечный метод (Polygon # getPaths) возвращает MVCArray из MVCArray из LatLngs, поскольку у многоугольника может быть любое количество путей, и каждый путь может иметь любое количество вершин.
Моя цель - преобразовать сгенерировать Observable из PolygonPathEvent
, который сработает при изменении родительского MVCArray любого дочернего MVCArray.
Создание Observables
Первый порядокбизнеса заключается в преобразовании addListener
в Observables.
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()));
}
Объединение наблюдаемых
Теперь для объединения, по-видимому, нам нужно использовать combineLatest
const pathsChanges$ = this.createMVCEventObservable(paths);
const pathChanges$ = combineLatest(paths.getArray().map(this.createMVCEventObservable));
return combineLatest(pathChanges$, pathsChanges$, (pathArr, paths) =>
new PolygonPathEvent(pathArr, paths);
);
Проблема заключается в том, что родительский MVCArray MVCArray может измениться, но combineLatest
принимает статический массив.Поэтому, когда добавляется новый путь, я не знаю, как заставить возвращаемый Observable также прослушивать этот новый путь.То же самое, если путь удален, я не знаю, как заставить возвращаемую наблюдаемую отписаться от удаленного пути.
Трубопровод к субъекту (неправильный подход)
Я думал о возвращении субъекта и простой подписке его на разные наблюдаемые при каждом изменении родителя MVCArray<MVCArray<LatLng>>
.
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;
Это работает, проблема в том, что подписка на исходные Observables (и addListener) происходит прямо в этом методе, а не когда подписка возвращается на Observable.
Заключение
Мне нужен какой-то оператор для этого.