【问题标题】:What is the better way to cancel a ngrx effect service call, based on a validation in the effect?根据效果中的验证,取消ngrx 效果服务调用的更好方法是什么?
【发布时间】:2019-08-23 17:23:33
【问题描述】:

我有这个在这个例子中调用电影服务的 ngrx 效果,但取决于一个值选择器,如果这个值在验证中符合预期,效果会发送一个新动作,这样我就避免调用服务因为条件。现在我不能在 if 块中使用另一个动作(这将更具描述性),因为这个错误:

类型 'Observable' 不可分配给类型 '可观察 | ((...args: any[]) => Observable)'.

类型 'Observable' 不可分配给类型 '可观察'.ts(2322).

处理这种情况的更好方法是什么?

loadMovies$ = createEffect(() => this.actions$.pipe(
        ofType('[Movies Page] Load Movies'),
        concatMap(action => of(action).pipe(withLatestFrom(this.store.select(getBlockBuster)))),
        mergeMap(([{payload}, foundBlockBuster]) => {
            if (!foundBlockBuster) {
                // in order to avoid errors we need to use this({ type: '[Movies API] Movies Loaded Success', payload: movies }))
                return of({ type: '[Movies] The block busters are rent' })
            }
            return this.moviesService.getAll()
                .pipe(
                    map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
                    catchError(() => of({ type: '[Movies API] Movies Loaded Error' }))
                )
            })
        )
    );

【问题讨论】:

    标签: javascript angular rxjs ngrx ngrx-effects


    【解决方案1】:

    发生此错误是因为您应该返回Observable<action>,而不是您的代码返回两种类型的对象文字(假设它是Action 类型)一种只有type 属性,另一种有typepayload。要解决此错误,请使用 Action 数组,然后将您的对象字面量推送到该数组中,然后像这样返回该数组:

    loadMovies$ = createEffect(() => this.actions$.pipe(
            ofType('[Movies Page] Load Movies'),
            concatMap(action => of(action).pipe(withLatestFrom(this.store.select(getBlockBuster)))),
            mergeMap(([{payload}, foundBlockBuster]) => {
    
                const actions = new Array<Action>();
    
                if (!foundBlockBuster) {
                    actions.push({ type: '[Movies] The block busters are rent' });
                    return actions;                
                }
                return this.moviesService.getAll()
                    .pipe(
                        mergeMap(movies => {
                          actions.push({ type: '[Movies API] Movies Loaded Success', payload: movies });
                          return actions;
                        }),
                        catchError(() => {
                          actions.push({ type: '[Movies API] Movies Loaded Error' });
                          return actions;
                        })
                    )
                })
            )
        );
    

    或者,您可以将对象文字类型转换为 &lt;Action&gt;,如下所示:

    <Action>{ type: '[Movies] The block busters are rent' }
    

    但我更喜欢使用数组,因为如果我的应用逻辑需要,数组允许调度多个操作。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-18
      • 2021-02-24
      • 1970-01-01
      • 2020-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      相关资源
      最近更新 更多