来自 ngrx 效果的多次 API 调用
Multiple API calls from ngrx effect
我是 ngrx store 和 redux 模式的新手。我在调度 updatePresentation$ 效果时遇到问题。调用 updatePresentation 操作时会调用效果。 updatePresentation 动作定义为:
export const updatePresentation = createAction(
'[Presentation] Update presentation',
props<{ presentation: Presentation, files: FileList | null }>()
);
updatePresentations$ 效果定义为:
updatePresentations$ = createEffect(() => {
return this.actions$
.pipe(
ofType(PresentationActions.updatePresentation),
switchMap(action =>
this.presentationService.updatePresentation(action.presentation)
.pipe(
tap(presentation => {
if (action.files !== null && action.files.length > 0) {
this.store.dispatch(PresentationActions.fileUpload({presentationId: presentation.id, files: action.files}));
}
}),
map(presentation => PresentationActions.loadPresentations({pageable: new Pageable()})),
catchError(error => of(PresentationActions.updatePresentationFailure({error})))
)
)
);
});
基本上,我想做的是更新演示文稿,当演示文稿更新时,我想检查 action.files 是否存在,以及它是否调度 fileUpload 操作。在此之后,我想通过 returning loadPresentations 操作(将调用 loadPresentations$ 效果)再次加载演示文稿。这是 fileUpload$ 和 loadPresentations$ 效果的样子:
loadPresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.loadPresentations),
concatMap(action => this.presentationService.getPresentations(action.pageable)
.pipe(
map(presentations => {
this.store.dispatch(setLoadingSpinner({status: false}));
return PresentationActions.loadPresentationsSuccess({page: presentations});
}),
catchError(error => of(PresentationActions.loadPresentationsFailure({error})))
)
)
);
});
uploadFile$ = createEffect(() => {
return this.actions$
.pipe(
ofType(PresentationActions.fileUpload),
concatMap(action =>
this.fileService.uploadFile(action.presentationId, action.files)
.pipe(
map(bool => PresentationActions.loadPresentations({pageable: new Pageable()})),
catchError(error => of(PresentationActions.fileUploadFailure))
)
)
);
});
正如您在 updatePresentations$ 效果中看到的那样,我正在尝试 return 应该调用 loadPresentations$ 效果的 loadPresentations 操作,但是这不起作用,我想是因为我应该 return 和将由 reducer 解决的操作?我该怎么做?
您的操作不需要绑定到减速器。我们仅使用动作来触发效果,然后效果会使用 reducer 分派动作。所以这应该没问题。
你的效果还行,之前也说了,可能还有优化的地方。否则我没有看到任何可疑的东西
updatePresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.updatePresentation),
concatMap(action =>
this.presentationService.updatePresentation(action.presentation).pipe(
map(presentation => {
// fileUpload dispatches loadPresentations anyway, is there a need to do it twice?
if (action.files !== null && action.files.length > 0) {
return PresentationActions.fileUpload({ presentationId: presentation.id, files: action.files });
}
return PresentationActions.loadPresentations({ pageable: new Pageable() });
}),
catchError(error => of(PresentationActions.updatePresentationFailure({ error })))
)
)
);
});
uploadFile$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.fileUpload),
concatMap(action =>
this.fileService.uploadFile(action.presentationId, action.files).pipe(
map(bool => PresentationActions.loadPresentations({ pageable: new Pageable() })),
catchError(error => of(PresentationActions.fileUploadFailure))
)
)
);
});
loadPresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.loadPresentations),
concatMap(action =>
this.presentationService.getPresentations(action.pageable).pipe(
// Use switch map to dispatch more actions at once
swithcMap(presentations => [
setLoadingSpinner({ status: false }),
PresentationActions.loadPresentationsSuccess({ page: presentations }),
]),
catchError(error => of(PresentationActions.loadPresentationsFailure({ error })))
)
)
);
});
同
我是 ngrx store 和 redux 模式的新手。我在调度 updatePresentation$ 效果时遇到问题。调用 updatePresentation 操作时会调用效果。 updatePresentation 动作定义为:
export const updatePresentation = createAction(
'[Presentation] Update presentation',
props<{ presentation: Presentation, files: FileList | null }>()
);
updatePresentations$ 效果定义为:
updatePresentations$ = createEffect(() => {
return this.actions$
.pipe(
ofType(PresentationActions.updatePresentation),
switchMap(action =>
this.presentationService.updatePresentation(action.presentation)
.pipe(
tap(presentation => {
if (action.files !== null && action.files.length > 0) {
this.store.dispatch(PresentationActions.fileUpload({presentationId: presentation.id, files: action.files}));
}
}),
map(presentation => PresentationActions.loadPresentations({pageable: new Pageable()})),
catchError(error => of(PresentationActions.updatePresentationFailure({error})))
)
)
);
});
基本上,我想做的是更新演示文稿,当演示文稿更新时,我想检查 action.files 是否存在,以及它是否调度 fileUpload 操作。在此之后,我想通过 returning loadPresentations 操作(将调用 loadPresentations$ 效果)再次加载演示文稿。这是 fileUpload$ 和 loadPresentations$ 效果的样子:
loadPresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.loadPresentations),
concatMap(action => this.presentationService.getPresentations(action.pageable)
.pipe(
map(presentations => {
this.store.dispatch(setLoadingSpinner({status: false}));
return PresentationActions.loadPresentationsSuccess({page: presentations});
}),
catchError(error => of(PresentationActions.loadPresentationsFailure({error})))
)
)
);
});
uploadFile$ = createEffect(() => {
return this.actions$
.pipe(
ofType(PresentationActions.fileUpload),
concatMap(action =>
this.fileService.uploadFile(action.presentationId, action.files)
.pipe(
map(bool => PresentationActions.loadPresentations({pageable: new Pageable()})),
catchError(error => of(PresentationActions.fileUploadFailure))
)
)
);
});
正如您在 updatePresentations$ 效果中看到的那样,我正在尝试 return 应该调用 loadPresentations$ 效果的 loadPresentations 操作,但是这不起作用,我想是因为我应该 return 和将由 reducer 解决的操作?我该怎么做?
您的操作不需要绑定到减速器。我们仅使用动作来触发效果,然后效果会使用 reducer 分派动作。所以这应该没问题。
你的效果还行,之前也说了,可能还有优化的地方。否则我没有看到任何可疑的东西
updatePresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.updatePresentation),
concatMap(action =>
this.presentationService.updatePresentation(action.presentation).pipe(
map(presentation => {
// fileUpload dispatches loadPresentations anyway, is there a need to do it twice?
if (action.files !== null && action.files.length > 0) {
return PresentationActions.fileUpload({ presentationId: presentation.id, files: action.files });
}
return PresentationActions.loadPresentations({ pageable: new Pageable() });
}),
catchError(error => of(PresentationActions.updatePresentationFailure({ error })))
)
)
);
});
uploadFile$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.fileUpload),
concatMap(action =>
this.fileService.uploadFile(action.presentationId, action.files).pipe(
map(bool => PresentationActions.loadPresentations({ pageable: new Pageable() })),
catchError(error => of(PresentationActions.fileUploadFailure))
)
)
);
});
loadPresentations$ = createEffect(() => {
return this.actions$.pipe(
ofType(PresentationActions.loadPresentations),
concatMap(action =>
this.presentationService.getPresentations(action.pageable).pipe(
// Use switch map to dispatch more actions at once
swithcMap(presentations => [
setLoadingSpinner({ status: false }),
PresentationActions.loadPresentationsSuccess({ page: presentations }),
]),
catchError(error => of(PresentationActions.loadPresentationsFailure({ error })))
)
)
);
});
同