angular NGRX:无法 select 基于 id 的 ngrx 实体中的单个值

angular NGRX: Not able to select single value in ngrx entity based on id

我正在尝试 select 通过实体状态中的 Id 生成一个对象。下面是我的减速器。

 export interface MessageState extends EntityState<Message> {
  // additional entities state properties
  loaded: boolean;
  loading: boolean;
}

export const adapter: EntityAdapter<Message> = createEntityAdapter<Message>({
  selectId: (msg: Message) => msg.messageId,
});

export const initialState: MessageState = adapter.getInitialState({
  // additional entity state properties
  loaded: false,
  loading: false,
});

export function reducer(state = initialState, action: MessageActionsUnion): MessageState {
  switch (action.type) {

    case MessageActionTypes.UPSERT_Message: {
      return { ...state, loading: true, loaded: false };
    }

    case MessageActionTypes.UPSERT_Message_SUCCESS: {
      return adapter.upsertOne(action.payload.Message,
        {
          ...state, loaded: true, loading: false,
        });

    }

    default: {
      return state;
    }
  }
}

下面是我的index.ts文件

export interface State extends fromRoot.AppState {
  queueModule: QueueState;
}

export interface QueueState {
  msgHeaders: fromMsgHeaders.MessageHeaderState
}

export const reducers: ActionReducerMap<QueueState> = {
  msgHeaders: fromMsgHeaders.reducer

};

export const getQueueState$ = createFeatureSelector<QueueState>('queueModule');

我正在尝试形成一个 select 或者当传递一个 Id 时 return 来自实体的值。

    export const selectMessages = createSelector(
      fromFeatures.getQueueState$,
      (state: fromFeatures.QueueState) => state.msgs
    );

    export const {
      selectAll: selectAllMessages,
      selectEntities: selectMessagesEntities,
      selectIds: selectMessagesIds,
      selectTotal: selectMessagesTotal
    } = adapter.getSelectors(selectMessages);

我看了很多资源,但是 none 很清楚如何通过传递 id select 一个对象。

@ngrx/entity 不提供 getOneById 选择器。

在大多数情况下,这是您不应该做的事情。

也就是说,有一些方法可以创建一个选择器来执行此操作,有关详细信息,请参阅(NgRx:参数化选择器)[https://blog.angularindepth.com/ngrx-parameterized-selector-e3f610529f8]

例如:

export const getCount = createSelector(
  getCounterValue, 
  (counter, props) => counter * props.multiply
);

export const selectCustomer = (id: string) => createSelector(
  selectCustomers,
  customers => customers[id]
);

@ngrx/entity 在他们引入 dictionary 的 v6.1.0 (ngrx entity changelog) 版本之后确实提供了 getEntityValueById。

因此,使用它,我能够通过以下方式通过实体的 ID 提取实体的单个值。

// in the selector
import { Dictionary} from '@ngrx/entity;

export const getMessageById = () => {
  return createSelector(
    selectMessagesEntities,                
    (entities: Dictionary<Message>, props: { messageId: number }) => {
      return entities[props.messageId];
    },
  );
};


//to call the selector


this.msg$ = this.store.pipe(select(
      fromStore.getMessageById(), { messageId: 10 }
    )).pipe(
      map(
        (message: Message) => {
          return this.msg = message;
        },
      )
    );

还记录了此方法的重要参考 here.