[英]How to map multiple Subject in an object literal to an object literal of corresponding Observable
I am working on a class in Angular and want to share a bunch of states belong to that class.我正在研究 Angular 中的 class 并想分享属于该 class 的一堆状态。 So I make a bunch of BehaviorSubject
所以我做了一堆BehaviorSubject
private subjects = {
a : new BehaviorSubject<A>(this.a),
b : new BehaviorSubject<B>(this.b),
c : new BehaviorSubject<C>(this.c),
d : new BehaviorSubject<D>(this.d),
e : new BehaviorSubject<E>(this.e),
}
To prevent leaking the Observer
side of the subjects and only expose the Observable
side, I make the subjects private and expose with observables:为了防止泄露主体的Observer
端并且只暴露Observable
端,我将主体设为私有并使用 observables 公开:
observables = {
a : this.subjects.a.pipe(share()),
b : this.subjects.b.pipe(share()),
c : this.subjects.c.pipe(share()),
d : this.subjects.d.pipe(share()),
e : this.subjects.e.pipe(share()),
}
I think the observables should be able to be generated from the subjects so that when I want to add more subjects, I don't need to modify the observables manually.我认为 observables 应该能够从主题中生成,这样当我想添加更多主题时,我不需要手动修改 observables。 Something like:就像是:
observables = (()=>{
let observables : {[Property in keyof typeof this.subjects]:Observable} = {}
for(let key in this.subjects)
{
observables[key] = this.subjects[key as keyof typeof this.subjects].pipe(share())
}
return observables;
})();
But here Observable
and share
do not know their generic type.但是这里的Observable
和share
不知道它们的泛型类型。 How can I make this work or if there is better pattern?我怎样才能使这项工作或是否有更好的模式?
As far as I am aware you don't need to share
the BehaviorSubject
observable as it is already hot via the BehaviorSubject
.据我所知,您不需要share
BehaviorSubject
可观察对象,因为它已经通过BehaviorSubject
很热。
You can solve the generic typing issues by using Mapped types :您可以使用Mapped types解决通用类型问题:
const subjects = {
a: new BehaviorSubject<number>(1),
b: new BehaviorSubject<string>('foo'),
c: new BehaviorSubject<boolean>(false),
};
// utility type to convert BehaviorSubject<T> to Observable<T>
// (can be inlined below instead)
type BehaviorSubjectToObservable<T> =
T extends BehaviorSubject<infer U> ? Observable<U> : never;
// create appropriate type for resulting object which has the same keys
// but maps to Observable<T>
// this ensures correct typing within the reduce
type Observables<T> = {
[P in keyof T]: BehaviorSubjectToObservable<T[P]>;
};
// transform the object
const observables = Object.entries(subjects).reduce(
(acc, [key, subject]) => ({ ...acc, ...{ [key]: subject.asObservable() } }),
{} as Observables<typeof subjects>,
);
// typeof observables.a = Observable<number>
// typeof observables.b = Observable<string>
// typeof observables.c = Observable<boolean>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.