Angular 如何在ngrx中使用带选择器的withLatestFrom?
我有一个ngrx应用程序,我不能通过我在组件中发送的有效载荷从选择器中获得有效值 我写了一个我处理的示例代码: 这是我的状态,一个简单的文档数组Angular 如何在ngrx中使用带选择器的withLatestFrom?,angular,rxjs,ngrx,Angular,Rxjs,Ngrx,我有一个ngrx应用程序,我不能通过我在组件中发送的有效载荷从选择器中获得有效值 我写了一个我处理的示例代码: 这是我的状态,一个简单的文档数组 export const initialState = { docs: [{ id: 1, name: "doc1" }, { id: 2, name: "doc2" }] }; export const reducer = createReducer( initialState, ); 我不处理这个问题的任何行动,这不是问题所在 在我的组
export const initialState = {
docs: [{ id: 1, name: "doc1" }, { id: 2, name: "doc2" }]
};
export const reducer = createReducer(
initialState,
);
我不处理这个问题的任何行动,这不是问题所在
在我的组件中,我使用选择器获取数组:
docs$ = this.store.pipe(select(fromStore.getAllDocs));
{{docs$ | async | json}}
减速器:
export const selectDocsState = createFeatureSelector("docs");
export const selectDocsStatusState = createSelector(
selectDocsState,
state => state["docs"]
);
export const getAllDocs = createSelector(
selectDocsStatusState,
getDocs
)
export const getById = createSelector(
selectDocsStatusState,
getDocs,
(state, docs, props) => {
console.log({ props });
return docs.docs.docs.filter(d => d.id === props.id);
}
)
我还有一个通过id获取的选择器:
{{docsById$ | async | json }}
docsById$ = this.store.pipe(select(fromStore.getById, { id: 1 }));
在减速器中:
export const selectDocsState = createFeatureSelector("docs");
export const selectDocsStatusState = createSelector(
selectDocsState,
state => state["docs"]
);
export const getAllDocs = createSelector(
selectDocsStatusState,
getDocs
)
export const getById = createSelector(
selectDocsStatusState,
getDocs,
(state, docs, props) => {
console.log({ props });
return docs.docs.docs.filter(d => d.id === props.id);
}
)
到目前为止一切都很好。我获取文档数组并显示它
现在,在我的组件中,我发布了一些操作并捕获副作用:
this.store.dispatch({ type: 'GET_DOC', payload: { id: 2 } });
实际上,我想知道这个id是否在商店里
因此,我将rxjs中的withLatestFrom与getById选择器一起使用
withLatestFrom((a: any) =>
this.store.pipe(select(fromDocs.getById, { id: a.payload.id }))
),
问题是我在获取存储实例时没有从选择器获取值
tap(v => {
console.log({ v });
}),
全面效果:
getDoc$ = createEffect(() =>
this.actions$.pipe(
ofType("GET_DOC"),
map(a => a),
tap(a => {
console.log({ a });
}),
withLatestFrom((a: any) =>
this.store.pipe(select(fromDocs.getById, { id: a.payload.id }))
),
tap(v => {
console.log({ v }); // <--------------- HERE SHOULD BE THE DOC AND THE ACTION.PAYLOAD, v[0].a.payload, v[1].id
}),
exhaustMap(payload => {
return of({ type: "SOME_ACTION", payload: null });
})
)
);
我在这里遗漏了什么?对于LatestFrom,它不采用复合函数,而是采用二次可观测源
您可以使用switchMap切换到新流并查看其值
尝试:
这在中有介绍,但我发现更有用:
在使用ofType运算符后,在聆听操作时,您会做两件主要的事情:
actions.pipe(
ofType('SOME_ACTION')
someMap(action => doSomething(action))
)
及
actions.pipe(
ofType('SOME_ACTION'),
withLatestFrom(store.select(someThing)),
someMap(([action, latest]) => doSomething(action, latest))
)
就效果而言,它们有两种不同的行为。第一个在动作被调度之前不会做任何事情,这是它应该做的
第二个命令立即订阅WithLatest,不管动作是否已调度。如果选择器使用的状态尚未初始化,则可能会出现意想不到的错误。为了让它变得懒惰,你最终不得不将它嵌套在一个平坦的可观察操作符中
actions.pipe(
ofType('SOME_ACTION'),
someMap(action =>
of(action).pipe(
withLatestFrom(store.select(someThing)),
someMap(([action, latest]) => doSomething(action, latest))
)
)
应用该方法可得到以下结果:
getDoc$ = createEffect(() => {
return this.actions$.pipe(
ofType(fromDocs.getDocument),
switchMap(action =>
of(action).pipe(
withLatestFrom(
this.store.select(fromDocs.getById, { id: action.payload.id })
),
map(([action, latest]) => {
return fromDocs.someAction();
})
)
)
);
});
不我还需要action对象,因此我使用withLatestFrom来获取action和LastFrom存储…SwitchMap采用复合函数,因此您可以将action的句柄作为参数a:any并切换到存储中的最新值。这可能是有用的,因为从使用链式方法到使用管道进行重构。在管道调用中立即计算的参数列表,而不是在控制下一次调用发生的链中的每个函数调用。如果是这样的话,我会说这是一次重构,实际上让设计变得更糟,而不是更好。这真是太棒了,谢谢分享。我有一个效果,需要访问一个尚未初始化的存储,这节省了一天。