You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Feature Store中清晰区分存储三类同类型候选对象

嘿,这个场景我之前在项目里处理过,咱们一步步来把三种候选对象清晰地存在Feature Store里:

方案思路:拆分候选状态并对应处理动作

核心思路是重构fromCandidates.reducer的状态结构,把全部、匹配、已分配三种候选对象作为独立子节点,同时给每个节点配上加载/错误状态,完美对应你提到的每个动作的成功/失败Effect。

1. 定义清晰的候选状态接口

先在fromCandidates文件里明确状态结构,让三种类型一目了然:

// from-candidates.ts
// 替换成你实际的候选对象类型
export interface Candidate {
  id: string;
  // 其他属性...
}

export interface CandidateGroupState {
  data: Candidate[];
  loading: boolean;
  error: string | null;
}

export interface CandidateState {
  all: CandidateGroupState;    // 全部候选对象
  matched: CandidateGroupState;// 匹配的候选对象
  assigned: CandidateGroupState;// 已分配的候选对象
}

// 初始状态
export const initialState: CandidateState = {
  all: { data: [], loading: false, error: null },
  matched: { data: [], loading: false, error: null },
  assigned: { data: [], loading: false, error: null },
};

2. 更新Candidate Reducer处理对应动作

修改fromCandidates.reducer,让它分别响应三个动作的发起、成功、失败状态,精准更新对应子节点:

// from-candidates.reducer.ts
import { Action, createReducer, on } from '@ngrx/store';
import { CandidateState, initialState } from './from-candidates';
// 导入你定义的动作类型
import { 
  loadCandidates, loadCandidatesSuccess, loadCandidatesFailure,
  loadMatchedCandidates, loadMatchedCandidatesSuccess, loadMatchedCandidatesFailure,
  loadAssignedCandidates, loadAssignedCandidatesSuccess, loadAssignedCandidatesFailure
} from './candidates.actions';

const _candidatesReducer = createReducer(
  initialState,
  // 处理全部候选的加载动作
  on(loadCandidates, state => ({
    ...state,
    all: { ...state.all, loading: true, error: null }
  })),
  on(loadCandidatesSuccess, (state, { candidates }) => ({
    ...state,
    all: { ...state.all, loading: false, data: candidates }
  })),
  on(loadCandidatesFailure, (state, { error }) => ({
    ...state,
    all: { ...state.all, loading: false, error }
  })),
  // 处理匹配候选的加载动作
  on(loadMatchedCandidates, state => ({
    ...state,
    matched: { ...state.matched, loading: true, error: null }
  })),
  on(loadMatchedCandidatesSuccess, (state, { candidates }) => ({
    ...state,
    matched: { ...state.matched, loading: false, data: candidates }
  })),
  on(loadMatchedCandidatesFailure, (state, { error }) => ({
    ...state,
    matched: { ...state.matched, loading: false, error }
  })),
  // 处理已分配候选的加载动作
  on(loadAssignedCandidates, state => ({
    ...state,
    assigned: { ...state.assigned, loading: true, error: null }
  })),
  on(loadAssignedCandidatesSuccess, (state, { candidates }) => ({
    ...state,
    assigned: { ...state.assigned, loading: false, data: candidates }
  })),
  on(loadAssignedCandidatesFailure, (state, { error }) => ({
    ...state,
    assigned: { ...state.assigned, loading: false, error }
  }))
);

export function candidatesReducer(state: CandidateState | undefined, action: Action) {
  return _candidatesReducer(state, action);
}

3. 保持Feature Store注入不变(内部结构已优化)

你原来的Feature Store注入代码完全不用改:

StoreModule.forFeature('candidates', combineReducers(fromStore.reducers))

现在candidates这个feature状态下,candidates子节点已经包含了all、matched、assigned三个清晰区分的候选集合,还有各自的加载/错误状态。

4. 用选择器简化组件访问

为了让组件更方便地获取对应类型的候选数据,可以创建专属选择器:

// from-candidates.selectors.ts
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { CandidateState } from './from-candidates';

const selectCandidatesState = createFeatureSelector<CandidateState>('candidates');

// 获取全部候选相关状态
export const selectAllCandidates = createSelector(
  selectCandidatesState,
  state => state.all.data
);
export const selectAllCandidatesLoading = createSelector(
  selectCandidatesState,
  state => state.all.loading
);

// 获取匹配候选相关状态
export const selectMatchedCandidates = createSelector(
  selectCandidatesState,
  state => state.matched.data
);
export const selectMatchedCandidatesLoading = createSelector(
  selectCandidatesState,
  state => state.matched.loading
);

// 获取已分配候选相关状态
export const selectAssignedCandidates = createSelector(
  selectCandidatesState,
  state => state.assigned.data
);
export const selectAssignedCandidatesLoading = createSelector(
  selectCandidatesState,
  state => state.assigned.loading
);

组件里直接调用这些选择器,就能轻松拿到对应类型的候选数据,还能基于加载状态做UI反馈。


内容的提问来源于stack exchange,提问作者Bhagavan Sankuratri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:20:27