gpt4 book ai didi

angular - 如何在 ngrx 中将 withLatestFrom 与选择器一起使用?

转载 作者:行者123 更新时间:2023-12-04 12:08:21 27 4
gpt4 key购买 nike

我有 ngrx 应用程序,我无法通过我在组件中发送的有效负载从效果中的选择器中获取值。

我写了一个我处理的示例代码:

这是我的状态,里面有一个简单的 docs 数组。

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}}

reducer :
export const selectDocsState = createFeatureSelector("docs");

export const selectDocsStatusState = createSelector(
selectDocsState,
state => state["docs"]
);

export const getAllDocs = createSelector(
selectDocsStatusState,
getDocs
)

我还有一个通过 id 获取的选择器:
{{docsById$ | async | json }}

docsById$ = this.store.pipe(select(fromStore.getById, { id: 1 }));

在 reducer 中:
export const getById = createSelector(
selectDocsStatusState,
getDocs,
(state, docs, props) => {
console.log({ props });
return docs.docs.docs.filter(d => d.id === props.id);
}
)

到目前为止一切都很好。我得到 docs 数组并显示它。

现在,在我的组件中,我分派(dispatch)了一些 Action 并按效果捕捉:
this.store.dispatch({ type: 'GET_DOC', payload: { id: 2 } });

结果我想知道这个 id 是否在商店里。

所以我使用 withLatestFrom来自带有 getById 选择器的 rxjs。
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 });
})
)
);

Here is my full example in stackbliz.

我在这里想念什么?

最佳答案

这在 NgRx Docs - Incorporating State 中有介绍但我找到了 Brandon Roberts github comment更有用:

There are two predominant things you do when listening to an action after using the ofType operator:

actions.pipe(
ofType('SOME_ACTION')
someMap(action => doSomething(action))
)

and

actions.pipe(
ofType('SOME_ACTION'),
withLatestFrom(store.select(someThing)),
someMap(([action, latest]) => doSomething(action, latest))
)

These have two different behaviors as far as effects are concerned. The first one doesn't do anything until the action is dispatched, which is what it should do.

The second one immediately subscribes to the withLatestFrom whether the action is dispatched yet or not. If that state used by the selector is not initialized yet, you could get an error you're not expecting. In order to make it "lazy" you end up having to nest it within a flattening observable operator.

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();
})
)
)
);
});

Stackblitz

关于angular - 如何在 ngrx 中将 withLatestFrom 与选择器一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60282687/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com