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

NgRx中如何让选择器间传递处理后的结果?

问题分析与修改方案

你的代码目前存在两个核心问题:

  • 三个子选择器是并列独立执行的,各自直接从原始状态取数据,没有实现“排序结果传给过滤”的链式依赖
  • 投影函数完全忽略了前三个选择器的返回值,直接取state.dataServices,等于前面的排序、过滤逻辑根本没生效

要实现选择器间的结果传递,有两种常用的修改方式:


方式一:嵌套选择器(链式依赖)

先基于原始数据创建排序选择器,再把排序后的结果作为输入传给过滤选择器,最后组合成最终的选择器:

export const selectSortedAndFilteredDataServices = (
    selectProperties: SelectProperties,
): MemoizedSelector<AppState, DataService[], DefaultProjectorFn<DataService[]>> => {
    // 先获取排序后的列表
    const sortedSelector = selectSortedDataServices(selectProperties.sort);
    // 基于排序后的列表创建过滤选择器
    const filteredSortedSelector = createSelector(
        sortedSelector,
        (sortedData) => selectFilteredDataServices(selectProperties.filter)({ dataServices: sortedData })
    );
    return filteredSortedSelector;
};

注:如果selectFilteredDataServices原本是基于AppState的选择器,需要调整它的输入逻辑,让它能接收包含dataServices的对象(或者直接改成接收数组的纯函数,灵活性更高)。


方式二:在投影函数中分步处理

如果不想嵌套选择器,可以在同一个createSelector的投影函数里,先执行排序,再用排序后的结果执行过滤:

export const selectSortedAndFilteredDataServices = (
    selectProperties: SelectProperties,
): MemoizedSelector<AppState, DataService[], DefaultProjectorFn<DataService[]>> =>
    createSelector(
        selectDataServices, // 只取原始数据一次
        (originalData) => {
            // 第一步:排序原始数据
            const sortedData = selectSortedDataServices(selectProperties.sort)({ dataServices: originalData });
            // 第二步:用排序后的结果执行过滤
            const filteredData = selectFilteredDataServices(selectProperties.filter)({ dataServices: sortedData });
            return filteredData;
        }
    );

这种方式逻辑更集中,所有处理步骤都在一个投影函数里完成,避免了多层嵌套。


额外优化建议

如果能把selectSortedDataServices和selectFilteredDataServices改造成纯函数(直接接收数组和参数,返回处理后的数组),代码会更简洁易维护:

// 改造后的排序纯函数
const sortDataServices = (data: DataService[], sortConfig: SortConfig): DataService[] => {
    // 这里写具体排序逻辑
};

// 改造后的过滤纯函数
const filterDataServices = (data: DataService[], filterConfig: FilterConfig): DataService[] => {
    // 这里写具体过滤逻辑
};

// 最终选择器
export const selectSortedAndFilteredDataServices = (
    selectProperties: SelectProperties,
): MemoizedSelector<AppState, DataService[], DefaultProjectorFn<DataService[]>> =>
    createSelector(
        selectDataServices,
        (originalData) => {
            const sorted = sortDataServices(originalData, selectProperties.sort);
            return filterDataServices(sorted, selectProperties.filter);
        }
    );

纯函数的方式更易测试和复用,也能避免选择器上下文的依赖问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:15:22