Angular12中如何让RxJS Observable在另一个Observable值为true后执行
问题描述
我正在使用Angular 12和RxJS开发一款电商类应用,创建了一个分类服务,通过GraphQL从服务端拉取分类数据并解析,方便站点其他模块调用。
目前遇到的问题是:如果用户直接进入使用了分类服务的页面,由于GraphQL请求尚未返回数据,服务会返回空响应。因此我计划创建一个isInitialized可观察对象,在数据加载处理完成后将其值设为true,让其他函数感知到服务已可正常使用。
服务核心代码如下:
@Injectable({ providedIn: 'root' }) export class ProductCategoriesService { adminQueryProductCategories=this.gql.adminQueryProductCategories(); isInitialized: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); constructor(private gql: GraphqlService) { this.adminQueryProductCategories.valueChanges.subscribe(({data})=>{ this.categories=data.adminQueryProductCategories; this.parseCategoryTree(this.categories); this.isInitialized.next(true); }); }
从productCategories$可观察对象拉取数据的函数实现如下:
getCategoryTitleByLabel(label: string): Observable<ProductCategory[]> { return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.category_label === label))); }
我需要让上述函数返回的Observable仅在isInitialized可观察对象的值为true后才执行,请问有什么解决方案?
更新说明1
整体需求为:用户浏览分类页面时,需要校验分类是否存在,不存在则路由到首页。首次加载时由于GraphQL请求尚未完成,用户总是会被直接路由到首页,相关代码如下:
ngOnInit(): void { this.route.params.subscribe(params => { this.label = params['category']; this.pcService.getCategoryTitleByLabel(this.label).subscribe((data)=>{ if (data.length !== 1) { this.router.navigate(['/']).finally(()=>{ //TODO: popup of some sort ? }); } else {
更新说明2
productCategories$的实现如下:
private productCategories = new BehaviorSubject<ProductCategory[]>([]); get productCategories$(): Observable<ProductCategory[]> { return this.productCategories; }
最终解决方案
将原有的BehaviorSubject替换为ReplaySubject即可解决问题,无需修改按标签查询分类的函数。
原有实现:
private productCategories = new BehaviorSubject<ProductCategory[]>([]); get productCategories$(): Observable<ProductCategory[]> { return this.productCategories; }
修改后实现:
productCategories$ = new ReplaySubject<ProductCategory[]>();
修改完成后即可生效,原有查询函数无需调整:
getCategoryTitleByLabel(label: string): Observable<ProductCategory[]> { return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.category_label === label))); }
内容的提问来源于stack exchange,提问作者ufk
相关产品推荐
相关产品推荐

