我有一个函数,可以根据http请求返回一个Observable。我想在内存中为这些函数创建一个存储,但是当我调用一个存储时,我想针对该函数的原始上下文发出此存储的新结果。
就我而言,我有一个主题服务,该主题服务具有一个商店,一个relaod内容功能并注册新的加载器功能。
主题服务类
....
contentLoaderRegistry = [];
public reloadRegistratedContents(){
this.contentLoaderRegistry.forEach((loader) => {
loader();
});
}
public registerThemeDependentContentLoader(loader:()=>Observable<SafeHtml>):Observable<SafeHtml>{
const loaderWrapper:() => Observable<SafeHtml> = ():Observable<SafeHtml> => {
return Observable.create((observer) => {
try{
observer.next( ...??? loader());
}catch(err){
observer.error(err);
}
return () => {
//observer.complete();
};
});
};
this.contentLoaderRegistry.push(loaderWrapper);
return loaderWrapper();
}
....
loader参数正在实现svg映像的http调用。更改主题后,将调用reloadRegistratedContents函数,并在此处使用新的svg内容对视图进行修补。
我还有一个应该做魔术的烟斗:
@Pipe({
name: 'themeDependentContent'
})
export class ThemeDependentContentPipe implements PipeTransform {
constructor(
private _theme:ThemeService,
private _http:HttpClient,
private _sanitizer:DomSanitizer
){}
transform(url:string):Observable<SafeHtml> {
let themeDependentContentLoader:()=>Observable<SafeHtml> = () => {
return this._http.get(url, {headers: new HttpHeaders().set('Content-Type', 'image/svg+xml'), responseType: 'text'}).pipe(map<string, SafeStyle>((svg:string) => {
return this._sanitizer.bypassSecurityTrustHtml(svg);
}));
}
return this._theme.registerThemeDependentContentLoader(themeDependentContentLoader);
}
}
如果registerThemeDependentContentLoader函数的结果可以在开始时发出(下一个)svg,则每次调用reloadRegistratedContents时都会很好。另一方面,此代码返回类似:Observable<Observable<SafeHtml>>
的{{1}}实例。因此,大概我应该包装可观察到的加载程序参数函数的结果,但我不知道该怎么做。
有更多经验的人可以帮助我吗? 谢谢您的时间和答复。
我可以使其与Subject一起使用,但我认为这不是最佳实践:
Observable<SafeHtml>
答案 0 :(得分:1)
我对您的用例不够了解,无法提供所需的确切代码,但是通常要回答如何根据另一个Observable的结果创建新的Observable的问题,我使用以下代码:
selectedProductSuppliers$ = this.selectedProduct$
.pipe(
switchMap(selectedProduct =>
forkJoin(selectedProduct.supplierIds.map(supplierId => this.http.get<Supplier>(`${this.suppliersUrl}/${supplierId}`)))
)
);
每次选择新产品时,该产品都会发送到this.selectedProduct$
流中。
这使用forkJoin
从所选产品的供应商列表中创建一个新的Observable,并通过http.get
获得每个供应商并加入结果。
通常,每当需要在另一个Observable中创建一个Observable时,都希望使用更高阶的映射运算符(例如switchMap,mergeMap或concatMap)。高阶映射运算符处理对内部Observable的订阅。
答案 1 :(得分:1)
您只需在loader()中传递观察者即可。订阅使其生效
try{
loader().subscribe(observer)
}catch(err){
observer.error(err);
}