NgRx ComponentStore实体附加属性更新与选择方法咨询
NgRx 实体附加属性操作解答
现有写法正确性说明
你当前仅为修改isLoading状态时调用adapter.setAll([], ...)的写法是错误的。setAll是实体适配器提供的全量替换实体集合的方法,你传入空数组作为第一个参数,会清空当前状态里存储的所有UserSelectionListDto实体数据,产生非预期的副作用。只有确实需要全量替换实体列表的场景(比如接口返回全量列表要覆盖旧数据),才需要调用适配器的实体修改方法。
你在接口请求成功回调里写的adapter.setAll(owners.items, { ...state, isLoading: false })是正确的,这个场景下确实需要用返回的新列表替换旧的实体数据,同时更新加载状态。
具体需求实现
仅更新isLoading属性
不需要调用实体适配器的任何方法,直接展开原状态覆盖目标属性即可,实体集合和其他附加属性会完整保留:
this.setState((state) => ({ ...state, isLoading: true // 要修改的目标值直接在此赋值即可 }));
请求报错、加载完成等所有仅需要更新加载状态的场景,都可以用这个写法,不会改动已存储的实体数据。
仅选择读取isLoading属性
通过NgRx的createSelector定义专属的属性选择器即可,步骤如下:
- 首先定义对应状态切片的Feature选择器,注意选择器里的key要和你注册状态时使用的feature key完全一致:
import { createFeatureSelector, createSelector } from '@ngrx/store'; // 替换'metricCreate'为你实际在StoreModule.forFeature中注册的状态key const selectMetricCreateState = createFeatureSelector<MetricCreateState>('metricCreate');
- 基于Feature选择器派生
isLoading属性的专用选择器:
export const selectMetricCreateIsLoading = createSelector( selectMetricCreateState, (state) => state.isLoading );
- 在组件或服务中使用时,直接从store中选择该字段即可:
// 组件内使用示例 isLoading$ = this.store.select(selectMetricCreateIsLoading);
补充说明:你之前直接从
adapter.getSelectors()解构的selectAll、selectEntities默认接收根状态作为入参,实际使用时需要传入Feature选择器作为参数,才能正确读取到当前切片下的实体数据,正确写法如下:export const { selectAll: selectAllMetricOwners, selectEntities: selectMetricOwnerEntities } = adapter.getSelectors(selectMetricCreateState);
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

