NgRx是否支持通过name字段而非id字段更新entity实体?
问题相关代码
export interface UpdateStr<T> { id: string; // 默认要求传入id作为实体更新匹配标识,业务需要改为按name匹配 changes: Partial<T>; }
问题内容
使用NgRx进行实体状态管理时,上述UpdateStr泛型接口默认要求传入id字段作为实体更新的匹配标识,但实际业务需求为通过name字段而非id字段匹配更新对应实体,该需求是否可以实现?
解答
该需求完全可以实现,NgRx Entity原生支持自定义实体匹配标识,不需要侵入式修改默认接口定义,常用实现方式有两种:
- 配置实体适配器自定义主键
初始化EntityAdapter时通过selectId配置项指定匹配字段,把name设为NgRx内部识别实体的唯一标识即可。配置完成后所有内置的增删改查方法都会自动以name作为匹配依据,不需要额外修改更新逻辑,示例代码:
后续调用// 业务实体类型示例 interface BusinessEntity { name: string; [key: string]: any; } // 创建适配器时指定selectId export const entityAdapter: EntityAdapter<BusinessEntity> = createEntityAdapter<BusinessEntity>({ selectId: (entity) => entity.name });adapter.updateOne、adapter.updateMany等更新方法时,原接口中传id的位置直接传入对应实体的name值即可,NgRx会自动匹配到目标实体完成更新。 - 自定义reducer更新逻辑
如果业务场景需要保留id作为默认主键,仅部分场景需要按name匹配更新,可以不依赖内置的update方法,自行在reducer中实现匹配逻辑:遍历实体集合找到name匹配的目标项后合并变更字段即可,示例逻辑:function updateByName(state: AppState, payload: { targetName: string; changes: Partial<BusinessEntity> }) { const entityIndex = state.entities.findIndex(item => item.name === payload.targetName); if (entityIndex < 0) return state; const newEntities = [...state.entities]; newEntities[entityIndex] = { ...newEntities[entityIndex], ...payload.changes }; return { ...state, entities: newEntities }; }
注意:如果选择
name作为实体匹配标识,必须保证业务范围内name值唯一,否则会出现匹配错误、实体被覆盖的问题。
内容的提问来源于stack exchange,提问作者Bitla Ramakrishna Sai
相关产品推荐
相关产品推荐

