简体   繁体   English

NGRX/entity:自定义选择器,获取具有特定键 === 值的实体

[英]NGRX/entity: custom selector that gets entities with a certain key === value

I believe this question has been asked in so few words, but none of the solutions provided work for my case (perhaps syntax deprecation, perhaps my implementation does something wrong)我相信这个问题已经用这么少的词问过了,但是没有一个解决方案为我的案例提供了工作(也许是语法弃用,也许我的实现做错了什么)

I am trying to select all GameInfo from my state which has a certain value in it's family property.我试图从我的州中选择所有在其家庭财产中具有一定价值的GameInfo Whatever solution I try when writing a custom, parameterized selector, I get an error like:无论我在编写自定义参数化选择器时尝试什么解决方案,都会收到如下错误:

No overload matches this call.
  The last overload gave the following error.
    Argument of type 'MemoizedSelector<object, Dictionary<GameInfo>, DefaultProjectorFn<Dictionary<GameInfo>>>' is not assignable to parameter of type '[SelectorWithProps<unknown, unknown, GameInfo[]>, SelectorWithProps<unknown, unknown, unknown>, SelectorWithProps<unknown, unknown, unknown>, SelectorWithProps<unknown, unknown, unknown>, SelectorWithProps<...>, SelectorWithProps<...>, SelectorWithProps<...>, SelectorWithProps<...>]'.ts(2769)
selector.d.ts(177, 25): The last overload is declared here.
const selectGameInfoEntities: MemoizedSelector<object, Dictionary<GameInfo>, DefaultProjectorFn<Dictionary<GameInfo>>>

my selector code我的选择器代码

export const selectGameInfoEntities = createSelector(
    fromGameInfo.getGameInfoState,
    fromGameInfo.selectGameInfoEntities
)

export const getFamily = (family: string) => 
    // how do we get the entities from the state 
    createSelector(
        selectGameInfoEntities, 
        (entities: GameInfo[]) => {
            entities.filter((item: GameInfo) => item.family === family)}
    );

game-info.reducer.ts游戏信息.reducer.ts

import * as actions from '../actions/game-info.actions';
import { EntityState, createEntityAdapter } from '@ngrx/entity';
import { createFeatureSelector, createReducer, on } from '@ngrx/store';
import { GameInfo } from 'src/app/models/game-info.model';


export const gameInfoAdapter = createEntityAdapter<GameInfo>();

export interface State extends EntityState<GameInfo> { }

const defaultGameInfo = {
    ids: [],
    entities : {}
}
export const getGameInfoState = createFeatureSelector<State>('gameInfo');

export const {
    selectIds,
    selectEntities,
    selectAll,
    selectTotal,
} = gameInfoAdapter.getSelectors(getGameInfoState);

// select the array of GameInfo ids
export const selectGameInfoIds = selectIds;
 
// select the dictionary of GameInfo entities
export const selectGameInfoEntities = selectEntities;
 
// select the array of GameInfo
export const selectAllGameInfos = selectAll;
 
// select the total GameInfo count
export const selectGameInfoTotal = selectTotal;

export const initialState: State = gameInfoAdapter.getInitialState(defaultGameInfo);

export const GameInfoReducer = createReducer(
  initialState,
    on(actions.readGameInfoSuccess, (state, {gameInfo}) => {return gameInfoAdapter.addMany(gameInfo, state)}),
  on(actions.createGameInfo, (state, action) => {return gameInfoAdapter.addOne(action, state)}),
  on(actions.deleteGameInfo, (state, action) => {return gameInfoAdapter.removeOne(action.id, state)}),
  on(actions.updateGameInfo, (state, action) => {return gameInfoAdapter.updateOne({id : action.id, changes : action.data}, state)})
);

Currently, this error appears when I hover over the selectGameInfoEntities parameter for the createSelector method.目前,当我将鼠标悬停在 createSelector 方法的 selectGameInfoEntities 参数上时,会出现此错误。 However, I have tried more straightforward approaches to accessing the state, and get similar errors about "no overload matching this call"但是,我尝试了更直接的方法来访问状态,并得到了关于“没有与此调用匹配的过载”的类似错误

I was hoping that perhaps someone could simply explain how selectors work within the context of entity.我希望也许有人可以简单地解释一下选择器在实体上下文中是如何工作的。 I am a little confused why I need this first selector argument when I already am calling selector on an observable of the store?当我已经在商店的可观察对象上调用选择器时,为什么我需要第一个选择器参数,我有点困惑? like this:像这样:

constructor(
  private gameInfoStore: Store<fromGameInfo.GameInfoState>,
  private gameStore : Store<fromGame.State>,
  private router : Router,
  private route : ActivatedRoute) { }

ngOnInit(): void {
  this.gameInfo$ = this.gameInfoStore.select(fromGame.selectAll)
  this.gameInfoStore.dispatch( gameInfoActions.readGameInfo() );

  this.game_categories$ = this.gameInfoStore.pipe(select(getFamily("category")))
  this.game_creators$ =  this.gameInfoStore.pipe(select(getFamily("creator")))
  this.game_platforms$ =  this.gameInfoStore.pipe(select(getFamily("platform")))
}

I imagine this could also be a mistake, but the error is coming from my custom selector definition我想这也可能是一个错误,但错误来自我的自定义选择器定义

This was a problem where we were really just overthinking/ over implementing.这是一个我们真的只是过度思考/过度实施的问题。

in our game-info.selector.ts :在我们的game-info.selector.ts

export const selectAllGameInfos = createSelector(
    fromGameInfo.getGameInfoState,
    fromGameInfo.selectAllGameInfos
)

export const getFamily = (family: string) => 
    createSelector(
        selectAllGameInfos, 
        (entities : GameInfo[]) => {
            return entities.filter((gameInfo : GameInfo) => gameInfo.family === family)
});

when this suffices:当这足够时:

export const getFamily = (family: string) => 
    createSelector(
        fromGameInfo.selectAllGameInfos, 
        (entities : GameInfo[]) => {
            return entities.filter((gameInfo : GameInfo) => gameInfo.family === family)
});

We redefined the selectAllGameInfos selector in the selector file, to take the feature selector selected substate as a first argument, because of some code we had seen in the NGRX entity documentation.我们在选择器文件中重新定义了 selectAllGameInfos 选择器,将特征选择器选择的子状态作为第一个参数,因为我们在 NGRX 实体文档中看到了一些代码。 This wasn't the right thing to do, but I was merely grasping at straws out of frustration.这不是正确的做法,但我只是出于沮丧而抓住了救命稻草。

Hopefully, a lesson for people struggling with NGRX, selectors and entity: keep it simple silly- work with the selectors that entityAdapter gives you- thats what they are meant for!希望能给在 NGRX、选择器和实体方面苦苦挣扎的人上一课:保持简单愚蠢——使用 entityAdapter 给你的选择器——这就是它们的意义所在!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM