商店中的状态非常简单:
const state = {
records: [1,2,3],
};
我有一个记录选择器:
export const getRecords = createSelector(getState, (state: State) => state.records));
我现在想要的是具有单独的选择器,用于按索引获取每个记录。 为此,我想通过以下方式用道具创建一个通用选择器:
export const getRecordByIndex = createSelector(
getRecords,
(state: State, { index }) => state.records[index]),
);
然后创建几个特定的选择器e。 g。:
export const getFirstRecord = createSelector(
getRecordByIndex(/* somehow pass index = 0 to this selector */),
(firstRecord) => firstRecord),
);
但是当我们在createSelector方法中使用参数时,我没有发现如何将参数传递给带有道具的选择器。有可能吗?
答案 0 :(得分:5)
来自此博客文章:https://blog.angularindepth.com/ngrx-parameterized-selector-e3f610529f8
从NgRx 6.1开始,选择器还接受一个额外的props参数。哪一个 意味着您现在可以定义一个选择器,如下所示:
this.m = 5;
for(var key in gui){
if(!gui.hasOwnProperty(key)){
if(gui[key].m == this.m-1){
//something
}
}
}
啊...但是重新阅读您的问题,您是在问然后如何构建使用该选择器的另一个选择器?上面链接的文章建议构建工厂功能。
答案 1 :(得分:2)
我设法向选择器提供了参数,但使用方式略有变化。示例:
export const selectReferentialsState = (state: AppState) => state.referentials;
export const referentialDataSelector = createSelector(
selectReferentialsState,
(state: ReferentialsState, props: { refType: Referential}) => state.data[props.refType]
);
this.availableRoles$ = this.store.select(state => referentialDataSelector(state, { refType: Referential.Role}));
答案 2 :(得分:1)
这可以通过@timdeschryver 在他的 comment regarding the deprecation of props
from ngrx selectors 中描述的“工厂选择器”来完成。
使用 OP 的请求,我将有以下实现:
export const getRecordByIndex = (index: number) => createSelector(
getRecords, (records) => records[index]
);
然后可以用作:
const record$ = this.store.select(getRecordByIndex(1));
既然“使用带有道具的选择器”被标记为 Deprecated in the ngrx documentation,这似乎是首选方式。
答案 3 :(得分:0)
我正在使用"@ngrx/entity": "7.2.0",
,并且可以看到将道具传递给每个选择器,例如,在我正在调用的组件中:
this.isActive$ = this.store.pipe(select(fromClient.isActive, { id: 'someid' }));
然后在我的减速器中,我有以下内容:
export const getClientState = createFeatureSelector<ClientState>('client');
export const getClient = createSelector(
getClientState,
(state, props) => {
// do something with props.id to get the client then:
return state;
}
);
export const isActive: = createSelector(
getClient, // props are passed to here
(state: any) => { // i don't add the props argument here, as i don't need them
return state.isActive;
}
);
答案 4 :(得分:0)
使用固定的选择器参数可以正常工作:
this.counter = this.store.pipe(
select(fromRoot.getCount, { multiply: 2 })
);
但是关于动态参数呢?
this.counter = this.store.pipe(
select(fromRoot.getCount, { multiply: this.getMultiplier() })
);
getMultiplier() {
...
return myUser.multiplier + magicFactor;
}
在我的应用中不起作用:-(((NgRx版本8)
答案 5 :(得分:0)
您可以使用投影仪功能:
export interface Record {
// Some sort of record interface
}
export interface State {
records: Record[];
}
export const getRecords = createSelector(
getState,
(state: State): Record[] => state.records)
);
export const getRecordByIndex = createSelector(
getRecords,
(records: Record[], { index }) => records[index]),
);
export const getFirstRecord = createSelector(
getRecords,
(records: Record[]) => getRecordByIndex.projector(records, { index: 0 })
);
答案 6 :(得分:0)
使用此库中的 mapSelectors reselect-mapper
看下面的例子
import { mapSelectors } from "reselect-mapper"
const getUserById = (state: State, id: string) => state.users[id]
const getPostByIndex = (state: State, index: number) => state.posts[index]
// now you can combine your selectors using mapSelectors
const getUserAndPost = mapSelectors({
user: getUserById,
post: getPostByIndex
}, map => map); // map signature is { user: User, post: Post }
// getUserAndPost selector has the following signature
// (state: State, params: { user: string, post: number }) => ({ user: User, post: Post })