Angular-NGRX优化:多状态订阅避免首次重复加载列表
优化Angular-NGRX首次加载多次请求问题
你的问题核心是三个独立的store.select订阅在首次加载时各自触发一次请求,导致重复调用loadResources。可以通过合并状态监听、过滤重复参数的方式解决,具体优化方案如下:
优化思路
- 合并状态监听:使用
combineLatest将三个状态(orderBy、filters、searchTerm)的Observable合并为一个,首次加载时只会在所有状态都有初始值后触发一次请求。 - 过滤重复请求:添加
distinctUntilChanged操作符,对比组合后的参数是否真正变化,避免因状态未实际变更而发起重复请求。 - 统一更新本地变量:在
tap操作中一次性更新组件内的orderBy、filters、searchTerm变量,同时执行取消全选的逻辑。 - 直接使用最新状态值:调用
loadResources时直接使用合并后的最新状态值,避免依赖组件本地变量的更新延迟。
优化后的代码
ngOnInit(): void { combineLatest([ this.store.select(state => state.shared.orderBy), this.store.select(state => state.shared.filters), this.store.select(state => state.shared.searchTerm) ]).pipe( takeUntil(this.onDestroy$), // 过滤参数未变化的情况,避免重复请求 distinctUntilChanged((prev, curr) => { return prev[0] === curr[0] && JSON.stringify(prev[1]) === JSON.stringify(curr[1]) && prev[2] === curr[2]; }), tap(([orderBy, filters, searchTerm]) => { // 统一更新本地变量 this.orderBy = orderBy; this.filters = filters; this.searchTerm = searchTerm; this._cmsFunctions.deselectAll('Resource'); }), switchMap(([orderBy, filters, searchTerm]) => { // 直接使用合并后的最新状态值作为参数 return this._dynamicComponentsService.loadResources( this.itemsToShow, this.tabCounter, orderBy, filters, searchTerm, this.company, this.workgroup, this.paramCode || 0 ); }) ).subscribe(); }
关键操作符说明
- combineLatest:当任意一个源Observable发出新值时,会将所有源的最新值组合成数组发出。首次加载时,三个状态都有初始值,因此只会触发一次组合后的数据流。
- distinctUntilChanged:通过自定义比较函数,判断前后两次的参数组合是否完全一致。这里对
filters使用JSON.stringify是因为它是对象类型,直接比较引用会不准确(如果需要更高效的比较,可以实现一个深比较函数)。 - switchMap:每次参数变化时,取消之前未完成的请求,发起新的请求,和原逻辑保持一致。
内容的提问来源于stack exchange,提问作者juanfranmozo
相关产品推荐
相关产品推荐

