NGRX:如何从内部效果使用不同的有效负载多次调用相同的服务
NGRX: How to call same service multiple time with different payload from inside effect
我不想在effect里面使用forkJoin
在我的效果中,我得到了一组 ID,在这些 ID 的帮助下,我想多次调用服务。
每次收到回复时,我都想发送一个操作来更新我的商店
@Injectable()
export class MovieEffects {
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
//here i am getting one array object via action, e.g. = [{id: 1},{id: 2},{id: 3},{id: 4} ]
//and here i want to call same service 4 time as per array length
// every time when get response i want to dispatch one action with response payload
mergeMap((action) => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => of({ type: '[Movies API] Movies Loaded Error' }))
)
)
)
);
constructor(
private actions$: Actions,
private moviesService: MoviesService
) {}
}
只需对您的 ID 数组中的每个执行一个操作,然后在该循环中调用您的服务,创建和订阅新的可观察对象,并在完成后调度操作。
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
tap((action) => {
action.payload.forEach(id =>
this.movieService.getMovie(id).pipe(
map(movie => this.store.dispatch(new fromStore.GetMovieSuccess(movie)),
catchError(() => this.store.dispatch(new fromStore.GetMovieFail(id)))
.subscribe();
}
)
), {dispatch: false}
);
我个人几乎总是为我的效果使用 {dispatch: false} 并手动分派事件,因为我不喜欢总是将它们放在效果的末尾,并且经常遇到一些其他语法问题。
您需要 return 您要更新商店的操作,而不是 map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
。
考虑到我想通过正在运行的方法 update() 和减速器(我正在更新商店数据的地方)更新我的商店,我会这样做:
loadMovies$ = this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
switchMap((action) => this.moviesService.getAll()
.pipe(
map(movies => new Actions.update()),
catchError(() => of({ type: '[Movies API] Movies Loaded Error' }))
)
)
);
您可以为此使用 merge
。
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
concatMap((action) => {
return merge(
...action.payload.map(id => this.movieService.getMovie(id).pipe(
map(movie => new fromStore.GetMovieSuccess(movie)),
catchError(() => of(new fromStore.GetMovieFail(id)))
))
)
})
);
我不想在effect里面使用forkJoin
在我的效果中,我得到了一组 ID,在这些 ID 的帮助下,我想多次调用服务。 每次收到回复时,我都想发送一个操作来更新我的商店
@Injectable()
export class MovieEffects {
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
//here i am getting one array object via action, e.g. = [{id: 1},{id: 2},{id: 3},{id: 4} ]
//and here i want to call same service 4 time as per array length
// every time when get response i want to dispatch one action with response payload
mergeMap((action) => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => of({ type: '[Movies API] Movies Loaded Error' }))
)
)
)
);
constructor(
private actions$: Actions,
private moviesService: MoviesService
) {}
}
只需对您的 ID 数组中的每个执行一个操作,然后在该循环中调用您的服务,创建和订阅新的可观察对象,并在完成后调度操作。
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
tap((action) => {
action.payload.forEach(id =>
this.movieService.getMovie(id).pipe(
map(movie => this.store.dispatch(new fromStore.GetMovieSuccess(movie)),
catchError(() => this.store.dispatch(new fromStore.GetMovieFail(id)))
.subscribe();
}
)
), {dispatch: false}
);
我个人几乎总是为我的效果使用 {dispatch: false} 并手动分派事件,因为我不喜欢总是将它们放在效果的末尾,并且经常遇到一些其他语法问题。
您需要 return 您要更新商店的操作,而不是 map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
。
考虑到我想通过正在运行的方法 update() 和减速器(我正在更新商店数据的地方)更新我的商店,我会这样做:
loadMovies$ = this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
switchMap((action) => this.moviesService.getAll()
.pipe(
map(movies => new Actions.update()),
catchError(() => of({ type: '[Movies API] Movies Loaded Error' }))
)
)
);
您可以为此使用 merge
。
loadMovies$ = createEffect(() =>
this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
concatMap((action) => {
return merge(
...action.payload.map(id => this.movieService.getMovie(id).pipe(
map(movie => new fromStore.GetMovieSuccess(movie)),
catchError(() => of(new fromStore.GetMovieFail(id)))
))
)
})
);