Я думаю, что закрытие, которое вы хотите получить, использует scan()
:
const filterChanges$ = new Subject()
const defaultFilter = {}
const filter$ = filterChanges$
.pipe(
scan((acc, mergeFilter) => {
return {
...acc,
...mergeFilter,
}
}, defaultFilter)
)
filter$.subscribe(console.log);
filterChanges$.next({ name: 'abc' })
filterChanges$.next({ num: 42 })
filterChanges$.next({ name: 'xyz' })
Демонстрация в реальном времени: https://stackblitz.com/edit/rxjs6-demo-ngqkzv?file=index.ts
Это выдаст:
{name: "abc"}
{name: "abc", num: 42}
{name: "xyz", num: 42}
Некоторое время назад я создал небольшую оболочку вокруг window.Proxy
под названием rxjs-observable-object
, которая позволяет вам обернуть любой объект и затем прослушать изменения на нем (https://github.com/martinsik/rxjs-ds#object):
import { map } from 'rxjs/operators';
import { ObservableObject } from 'rxjs-observable-object';
const defaultFilter = {}
const { proxy, events } = new ObservableObject(defaultFilter);
const filter$ = events.onSet
.pipe(
map(({ target }) => target)
)
filter$.subscribe(console.log);
proxy['name'] = 'abc';
proxy['num'] = 42;
proxy['name'] = 'xyz';
Демонстрация в реальном времени: https://stackblitz.com/edit/rxjs6-demo-hojjkk?file=index.ts
Однако rxjs-observable-object
немного устарел и требует также установленного пакета rxjs-comapt
.
Вывод для обоих примеров одинаков.