angular - @ngrx/store pre-load guard catch 错误

标签 angular rxjs ngrx ngrx-effects ngrx-store-4.0

我正在使用 @ngrx/store 开发 Angular 守卫来检查状态是否已经加载,我遇到了一个问题,如果我使用过滤器,canActivate 方法永远不会返回。

这是 GetCompanies 操作的示例效果:

return this.companiesService.getCompanies()
  .pipe(
    map(companies => new companiesActions.GetCompaniesSuccess(companies)),
    catchError(error => Observable.of(new companiesActions.GetCompaniesFail(error)))
  )

如果出现错误,我将调度 GetCompaniesFail 操作并将用户重定向到 /login 页面。没关系,有趣的部分是守卫。

@Injectable()
export class CompaniesGuard implements CanActivate {
  constructor(
    private store: Store<AppState>,
    private router: Router
  ) {}

  canActivate(): Observable<boolean> {
    return this.checkStore()
      .pipe(
        switchMap(() => Observable.of(true)),
        catchError(() => Observable.of(false))
      );
  }

  checkStore(): Observable<boolean> {
    return this.store.select(getCompaniesLoaded)
      .pipe(
        tap(loaded => {
          if (!loaded) {
            this.store.dispatch(new companiesActions.GetCompanies());
          }
        }),
        filter(loaded => loaded),
        take(1)
      );
  }
}

如果出现错误且加载不为假,canActivate 将不会返回任何内容,因为 checkStore 不执行任何操作。

如果我将 filter 更改为 map 它可以工作,但它只采用第一个值为 false 的值,即使数据将成功加载.

我错过了什么?我该如何处理那里的 HTTP 错误?有没有办法等待特定状态或在 checkStore 中抛出错误?

提前致谢!

最佳答案

如果您稍微分离职责,这似乎更容易处理。

无论如何,您都应该运行 checkStore,而不是直接依赖于它的结果。相反,让商店通知您成功或失败并返回该结果。

请注意,ngrx 和 redux 鼓励单向数据流来简化应用逻辑。

商店属性 getCompaniesLoadedStatus 初始化为 initial,并在 内设置为successfailed companiesActions.GetCompaniesSuccesscompaniesActions.GetCompaniesFail

重试在服务中处理(更接近于获取)。

canActivate(): Observable<boolean> {
  this.checkStore();
  return this.store.select(getCompaniesLoadedStatus).pipe(
    filter(status => status !== 'initial'),
    map(status => status === 'success' ? true : false )
  );
}

checkStore(): void {
  this.store.select(getCompaniesLoadedStatus).pipe(
    take(1)  // so that unsubscribe is not needed
  ).subscribe(status =>
    if (status === 'initial') { 
      this.store.dispatch(new companiesActions.GetCompanies());
    }
  );
}

关于angular - @ngrx/store pre-load guard catch 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48749478/

相关文章:

javascript - 在 Angular 5 中,如何对点击事件进行分组并仅在用户停止点击时发出一次

angular - 在 Azure 上部署 Angular 存在静态网站回退问题

rest - 使用 Angular2 ngrx 的类似 Twitter 的应用程序。构建 AppState

angular - 基于有效载荷而不是效果取消可观察

angular - ngrx - createSelector 与 Observable.combineLatest

angular - 升级到 Angular4 后找不到名称 'require'

javascript - 如何保护从 Angular 2 到 Express Server 的 http 帖子

javascript - 为什么 jest.useFakeTimers 不适用于 RxJs Observable 延迟

angular - Angular 2 服务中的 Observables 与变量

javascript - RXJS mixLatest/zip 问题