如何使用@ ngrx / entity通过ID选择单个对象

vac*_*hee 6 ngrx angular ngrx-entity

我想使用@ ngrx / entity从实体映射中按单个ID选择一个实体,或按ID数组选择一个实体数组。

我不希望当实体集合获得新元素或实体项更改时触发组件内部的选择订阅,而我根本没有选择。

当我使用selectEntities选择器,然后从结果中选择ID时,这显然发生在我身上。

那么如何从实体集合中按ID选择1或n个项目?

Jor*_*ray 20

NgRx通过最后一个参数传递给选择器函数来支持参数化选择props

export const selectEntity = createSelector(
  selectEntities,
  (entities, props) => entities[props.id]
);

export const selectEntitiesByID = createSelector(
  selectEntities,
  (entities, props) => props.ids.map(id => entities[id])
);
Run Code Online (Sandbox Code Playgroud)

这些完全按照您的预期调用:

this.store.pipe(
  select(selectEntity, { id: someID })
);

this.store.pipe(
  select(selectEntitiesByID, { ids: arrayOfIDs })
);
Run Code Online (Sandbox Code Playgroud)

如果您的 ID 不会改变,您可以将它们重构为工厂函数

export const selectEntity = id => createSelector(
  selectEntities,
  entities => entities[id]
);

export const selectEntitiesByID = ids => createSelector(
  selectEntities,
  entities => ids.map(id => entities[id])
);
Run Code Online (Sandbox Code Playgroud)

被称为:

this.store.pipe(
  select(selectEntity(someID))
);

this.store.pipe(
  select(selectEntitiesByID(arrayOfIDs))
);
Run Code Online (Sandbox Code Playgroud)

  • 否决票是一个有用的信号,表明某些内容可能是错误或遗漏的,我感谢您花时间,但评论会非常有帮助 - 否则,我只能猜测我可能会错过目标!目前,我还不确定,所以我将保留我的答案。 (3认同)

mar*_*den 1

对于这两种情况,我都会使用专用选择器来处理它:

    // single entity
    export const singleEntitySelector = createSelector(

       // you should have set it up already 
       yourEntitiesObjSelector,

       // here I assume you have set up router reducer state or any other 
    state slice where you keep single entity id
       yourIdSelector,

       // then you just return single entity as entities will be an object
       (entities, id) => entities[id]
    );

    // same for array (you will have to store selected ids also on the 
    state tree)
    export const selectedEntitiesArraySelector = createSelector(

       // you should have set it up already 
       yourEntitiesObjSelector,

       // here I assume you have set up selected ids store slice
       yourSelectedIdsArraySelector,

       // then you just return entities array reducing ids array
       (entities, idsArray) => idsArray.reduce((acc, id) => {
          return entities[id] ? [...acc, entities[id]] : acc;
       }, [])
    );
Run Code Online (Sandbox Code Playgroud)

async然后,您只需在组件中使用这些选择器,像往常一样用管道反映视图中的变化。它们将反映所有更改:单个实体 id 更改或 ids 数组更改。不需要订阅任何内容,除非您的组件中有一些额外的逻辑。