2

如果这是一些问题的重复,我最近很抱歉,但我找不到任何解决我的问题的方法。

我有警卫,现在我需要从调用 http 服务并将用户重定向到错误状态的副作用中捕获错误。尝试添加catchError,但如果我从服务器端收到错误,我什至不会去那里。

守卫.ts

canActivate(): Observable<boolean> {
    return this.store
        .select(fromDataStore.getDatasLoaded)
        .pipe(
            withLatestFrom(this.store.select(fromDataStore.getDataLoading)),
            map(([loaded, loading]) => {
                if (!loaded && !loading) {
                    this.store.dispatch(new fromDataStore.LoadData());
                }
                return loaded;
            }),
            filter(loaded => loaded),
            take(1),
            catchError(error => {
                // redirect user to error state
            })
        );
}

效果.ts

 @Effect() loadData$: Observable<Action> = this.actions$.ofType(DataActionTypes.LoadData)
    .pipe(
        mergeMap(() =>
            this.dataApiService.loadData()
                .pipe(
                    map(data => ({
                        type: DataActionTypes.LoadDataSuccess,
                        payload: data
                    })),
                    catchError(() => of({ type: DataActionTypes.LoadDataFailure }))
                )
        )
    );

减速器.ts

case DataActionTypes.LoadData: {
        return {
            ...state,
            data: {
                ...state.data,
                isLoading: true
            }
        };
    }
    case DataActionTypes.LoadDataSuccess: {
        return {
            ...state,
            data: {
                ...dataAdapter.addMany(action.payload, state.data),
                isLoaded: true,
                isLoading: false
            }
        };
    }
    case DataActionTypes.LoadDataFailure: {
        return {
            ...state,
            data: {
                ...state.data,
                isLoaded: true,
                isLoading: false
            }
        };
    }
    default: {
        return state;
    }
4

1 回答 1

3

在 reducer 中处理 LoadDataFailure 时,可以将错误添加到状态中。

在警卫中,您可以添加一个 withLatestFrom 并选择状态的那部分,错误。而不是catchError,这里没有错误,所以它不会捕获任何东西。

如果您没有错误,您可以导航到该页面,如果您有错误,则将用户重定向到您需要的内容。

您还可以对代码进行一些重构,例如在守卫进入时始终触发加载操作,将 if 语句移到外面,并使用 isDataLoaded 流。

就像是:

this.store.dispatch(new fromDataStore.LoadData());

return this.store
        .select(fromDataStore.getDatasLoaded)
        .filter(Boolean),
        .withLatestFrom(fromDataStore.getError)
        ...
于 2018-12-05T13:06:35.467 回答