共享RxJS主题用于Angular 2中的双向数据绑定 [英] Shared RxJS subject for bidirectional data binding in Angular 2
问题描述
我有应用设置的单件服务
I have a singleton service for app settings
class Setting {
get foo() {
return storage.get('foo');
}
set foo(val)
storage.set('foo', val);
}
}
在组件的视图中绑定为 setting.foo
。
that is bound in components' views as setting.foo
.
因为存储
来电可能代价高昂,因为它可能是异步的,我宁愿用RxJS主题替换getter / setter,它可以在需要时更新并读取 storage
。
Because storage
calls may be costly and because it may be asynchronous, I would prefer to replace getter/setter with RxJS subject that could update and read storage
whenever needed.
所以我将它重构为
class Setting {
constructor() {
this.fooSubject = new ReplaySubject(1);
fooSubject.subscribe((val) => {
storage.set('foo', val);
});
this.foo$ = this.fooSubject
.map(() => storage.get('foo'))
.publishReplay(1).refCount();
}
并使用它像 setting.foo $ | async
和 setting.fooSubject.next(newFoo)
。看起来昂贵的 storage.get
调用现在被缓存。
and using it like setting.foo$ | async
and setting.fooSubject.next(newFoo)
. It looks like costly storage.get
calls are cached now.
有两个问题。
第一个是 fooSubject
subject和 foo $
observable应该是选择一个主题是公开可用的,因为它应该是一个可观察者和一个观察者。
The first one is that both fooSubject
subject and foo$
observable should be publicly available to make this work, while a subject was chosen because it is supposed to be both an observable and an observer.
可以 foo $
被设为设置
服务的单个主题属性,因此可以使用订阅订阅(...)
并使用更新下一个(...)
?
Can foo$
be made to be a single Subject property of Setting
service, so it could be subscribed with subscribe(...)
and updated with next(...)
?
第二个是代码仍然是同步的。
The second one is that the code is still synchronous.
如何处理 storage.get
和的情况返回承诺的storage.set
?
推荐答案
获得有副作用的主题非常容易通过扩展 AnonymousSubject
(一个 Subject.create(...)
工厂的类)。生成的主题获得目的地
和来源
包含原始主题和可观察对象的属性。
It was really easy to get a subject with side effects by extending AnonymousSubject
(a class for Subject.create(...)
factory). Resulting subject gets destination
and source
properties that hold original subject and observable.
class FooSharedSubject extends AnonymousSubject {
constructor() {
const subject = new BehaviorSubject('');
const observable = subject.asObservable()
.mergeMap((value) => promisedStorage.get('foo'))
.publishReplay(1)
.refCount();
super(subject, observable);
}
next(value): void {
promisedStorage.set('foo', value)).then(
() => this.destination.next(value),
() => this.destination.error(value)
);
}
}
这篇关于共享RxJS主题用于Angular 2中的双向数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!