NgRx 如何按顺序分派 2 个动作
NgRx how to dispatch 2 actions in order
我似乎无法找到一种使用 NgRx(不是 RxJS 样式)的方法来在一个效果中分派 2 个 Actions。
我想(按此顺序):
- 删除数据库中带有效果的电影,
- 调度 deleteMovieSuccess
- dispatch getMovies(之后我需要重新加载所有电影!)
我试着像下面那样做,但它只触发了第一个动作,我看不到另一个动作:
在我的日志中我可以看到:
- [电影列表]删除电影
- [电影列表]获取电影
- [电影列表]获取电影成功
我有以下操作:
export const getMovies = createAction('[Movie List] Get Movies', props<{search: string, page: number, limit: number}>());
export const getMoviesSuccess = createAction('[Movies List] Get Movies Success', props<{ search: string, page: number, limit: number }>());
export const deleteMovie = createAction('[Movie List] Remove Movie', props<{ movieToDelete: Movie, search: string, page: number, limit: number }>());
export const deleteMovieSuccess = createAction('[Movie List] Remove Movie Success', props<{ movieToDelete: Movie }>());
以及以下效果:
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
map(() => MovieActions.getMovies({search, page, limit})),
catchError(() => EMPTY)
)
)
)
);
如何按此顺序触发 BOTH、deleteMoviesSuccess 和 getMovies?
我也尝试过使用 switchMap 和 faltMap,但从来没有正确调度过两个 Action。
我似乎无法理解,如何以迭代方式进行调度,但我的特殊用例确实需要它。
非常感谢任何帮助。
您可以使用 switchMap
运算符来 return 一组操作。
例如,而不是;
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
map(() => MovieActions.getMovies({search, page, limit})),
catchError(() => EMPTY)
)
)
)
);
你可以试试;
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
switchMap(() => [MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete}),
MovieActions.getMovies({search, page, limit})]),
catchError(() => EMPTY)
)
)
)
);
你不应该因为一个效果而分派两个动作。而是发送某种成功动作,然后在其他效果中对此做出反应。 Read here
您可以创建连锁效应:
- 调度删除操作
- 删除调度 deleteSuccess 操作完成时
- deleteSuccess 操作触发 loadMovies 效果
- 在 loadMovies 成功时,reducer 会执行一些设置操作
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) => this.moviesService.deleteMovie(movieToDelete).pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
catchError(() => EMPTY)
))
));
loadMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovieSuccess),
mergeMap(() => this.moviesService.loadMovies().pipe(
map(movies => MovieActions.setMovies({ movies })),
catchError(() => EMPTY)
))
));
编辑
此外,您可以将这些参数保存在商店中,而不是传递限制或搜索等参数。这样做可以让您在需要时始终访问那些有效的内容。 NgRx 文档有一个很好的例子,说明如何在效果中进行选择。 ngrx.io/api/effects/concatLatestFrom
我似乎无法找到一种使用 NgRx(不是 RxJS 样式)的方法来在一个效果中分派 2 个 Actions。
我想(按此顺序):
- 删除数据库中带有效果的电影,
- 调度 deleteMovieSuccess
- dispatch getMovies(之后我需要重新加载所有电影!)
我试着像下面那样做,但它只触发了第一个动作,我看不到另一个动作: 在我的日志中我可以看到:
- [电影列表]删除电影
- [电影列表]获取电影
- [电影列表]获取电影成功
我有以下操作:
export const getMovies = createAction('[Movie List] Get Movies', props<{search: string, page: number, limit: number}>());
export const getMoviesSuccess = createAction('[Movies List] Get Movies Success', props<{ search: string, page: number, limit: number }>());
export const deleteMovie = createAction('[Movie List] Remove Movie', props<{ movieToDelete: Movie, search: string, page: number, limit: number }>());
export const deleteMovieSuccess = createAction('[Movie List] Remove Movie Success', props<{ movieToDelete: Movie }>());
以及以下效果:
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
map(() => MovieActions.getMovies({search, page, limit})),
catchError(() => EMPTY)
)
)
)
);
如何按此顺序触发 BOTH、deleteMoviesSuccess 和 getMovies?
我也尝试过使用 switchMap 和 faltMap,但从来没有正确调度过两个 Action。 我似乎无法理解,如何以迭代方式进行调度,但我的特殊用例确实需要它。
非常感谢任何帮助。
您可以使用 switchMap
运算符来 return 一组操作。
例如,而不是;
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
map(() => MovieActions.getMovies({search, page, limit})),
catchError(() => EMPTY)
)
)
)
);
你可以试试;
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) =>
this.moviesService.deleteMovie(movieToDelete)
.pipe(
switchMap(() => [MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete}),
MovieActions.getMovies({search, page, limit})]),
catchError(() => EMPTY)
)
)
)
);
你不应该因为一个效果而分派两个动作。而是发送某种成功动作,然后在其他效果中对此做出反应。 Read here
您可以创建连锁效应:
- 调度删除操作
- 删除调度 deleteSuccess 操作完成时
- deleteSuccess 操作触发 loadMovies 效果
- 在 loadMovies 成功时,reducer 会执行一些设置操作
deleteMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovie),
mergeMap(({movieToDelete, search, page, limit}) => this.moviesService.deleteMovie(movieToDelete).pipe(
map(() => MovieActions.deleteMovieSuccess({movieToDelete: movieToDelete})),
catchError(() => EMPTY)
))
));
loadMovie$ = createEffect(() => this.actions$.pipe(
ofType(MovieActions.deleteMovieSuccess),
mergeMap(() => this.moviesService.loadMovies().pipe(
map(movies => MovieActions.setMovies({ movies })),
catchError(() => EMPTY)
))
));
编辑
此外,您可以将这些参数保存在商店中,而不是传递限制或搜索等参数。这样做可以让您在需要时始终访问那些有效的内容。 NgRx 文档有一个很好的例子,说明如何在效果中进行选择。 ngrx.io/api/effects/concatLatestFrom