1

我已经扩展了 @ngrx/entity 状态存储,以包含应从服务器检索的实体的加载值。

const adapter = createEntityAdapter<A>();
export interface AState extends EntityState<A> {
  loading: {
    projects: {
      [id: string]: boolean
    },
    collections: {
      [id: string]: boolean
    }
  };
}
const initialState: AState = adapter.getInitialState({
  loading: {
    projects: {},
    collections: {}
  }
});

为了能够显示这个加载值,我使用了这个选择器:

export const getRunsLoadingByProject = createSelector(
  (state: AppState) => state.a,
  (state: AState, Id: number) => {
    return !!state.loading.projects[Id];
  }
);

这在第一次加载时效果很好。实体和加载值得到更新,选择器就像一个魅力。问题发生在我需要在网站上的“更新”按钮上。一旦来自服务器的实体状态与存储中已经存在的状态相同,选择器就会停止检索新的加载状态。使用 devtools 我可以看到状态以正确的方式更改(加载标志设置为 true 然后为 false)。

它似乎只是选择器。这是选择器仅在实体更改时触发的@ngrx/entities 的怪癖吗?还是我错过了什么?

编辑:减速机

export function aReducer(state: AState = initialState, action: AEffectsActions): RunState {
  switch (action.type) {
    case AEffectsActionTypes.LOAD_RUN: {
      const newState = { ...state };
      newState.loading.projects[action.payload.toString()] = true;
      return newState;
    }
    case AEffectsActionTypes.LOAD_RUN_SUCCESS: {
      const newState = adapter.addMany(action.runs, state);
      newState.loading.projects[action.projectId] = false;
      return newState;
    }
    default:
      return state;
  }

} 
4

1 回答 1

1

扩展运算符仅在顶层“克隆”,您的选择器没有被执行,因为对的引用loading.projects仍然相同。

因此,您必须执行以下操作。

return {
   ...state,
   loading: {
      ...state.loading,
      projects: {
        ...state.loading.projects,
        [action.payload.toString()]: true
      }

   }
};
于 2018-09-14T09:56:02.883 回答