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

如何在NgRx中按任意属性对实体排序,能否从主store获取sort状态?

实现方案

你无法直接向sortComparer中注入服务或访问全局Store,因为NgRx的Reducer设计为纯函数,不允许引入外部依赖。可以通过以下两种成熟方案实现基于State中排序配置的动态排序:


方案1:在Selector层实现排序(更推荐)

排序属于派生状态,放在Selector中处理是最符合NgRx设计规范的做法,无需修改Reducer和EntityAdapter的初始化逻辑:

  1. 初始化EntityAdapter时移除固定的sortComparer配置
// reducer.ts
export const adapter: EntityAdapter<ProductDetails> =
  createEntityAdapter<ProductDetails>();

export const initialState: ProductsState = adapter.getInitialState({
  productType: null,
  productTags: [],
  sort: {
    key: 'name',
    order: 1
  }
});
  1. 编写带排序逻辑的Selector,自动关联State中的排序配置
// selector.ts
import { createSelector } from '@ngrx/store';
import { selectProductsState } from './products.selectors';

// 先获取原始的全量实体列表
const selectAllProducts = createSelector(
  selectProductsState,
  state => adapter.selectAll(state)
);

// 关联排序状态,返回排序后的列表
export const selectSortedProducts = createSelector(
  selectAllProducts,
  selectProductsState,
  (products, state) => {
    const { sort } = state;
    // 拷贝数组后排序避免修改原引用
    return [...products].sort((a, b) => {
      const itemA = a[sort.key];
      const itemB = b[sort.key];
      return itemA < itemB
        ? -1 * sort.order
        : itemA > itemB
        ? sort.order
        : 0;
    });
  }
);

该方案的优势:排序逻辑与Reducer解耦,Selector自带缓存机制,仅当实体列表或排序配置变更时才会重新执行排序,性能损耗极低。


方案2:排序配置变更时重新设置实体

如果你需要使用EntityAdapter内置的排序能力,可以在触发排序配置更新的Action处理逻辑中,重新用新的排序规则设置全量实体:

// reducer.ts
import { createReducer, on } from '@ngrx/store';
import { updateSort } from './products.actions';

const productsReducer = createReducer(
  initialState,
  // 处理更新排序配置的Action
  on(updateSort, (state, { newSort }) => {
    // 拿到当前所有实体
    const allProducts = adapter.selectAll(state);
    // 按新排序规则排序后重新存入State
    return adapter.setAll(allProducts, {
      ...state,
      sort: newSort
    });
  })
);

该方案适合实体数量较少的场景,后续调用adapter.selectAll即可直接获取排序后的结果,无需在Selector额外处理。


内容的提问来源于stack exchange,提问作者JanuszFrontEnd'u

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:15:08