【问题标题】:Check for existence of element in possibly to be loaded list in ngrx检查ngrx中可能要加载的列表中是否存在元素
【发布时间】:2019-10-01 01:40:04
【问题描述】:

我正在尝试在警卫中构建一系列 RXJS 命令,以便在一个简单的库(如书籍)应用程序中实现此结果:

  • 到商店打卡
  • 如果状态没有加载,触发一个动作
  • 加载后,过滤数据以找到一个特定项目
  • 如果找到,允许访问页面,如果没有,发送到 404

我已经苦苦挣扎了一段时间,根据 Angular 6 版或标准,在网上查找并没有给出答案......如果之前加载了商店,我已经成功地做了什么来创建它击中守卫,但如果它需要获取数据,它会无限循环。

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
  return this.store.pipe(
    select(state => state.books),
    tap(state => {
      if (!state.loaded) {
        this.store.dispatch(new BooksActions.Load());
      }
    }),
    filter(state => state.loaded),
    take(1),
    map(state => state.list.find(book => book.id === route.params['id'])),
    map((book) => {
      if(!!book) return true;
      this.router.navigate(['/404']);
      return false;
    })
  );
}

非常感谢!

【问题讨论】:

    标签: angular rxjs ngrx angular-guards


    【解决方案1】:

    问题出在这部分:

    select(state => state.books),
        tap(state => {
          if (!state.loaded) {
            this.store.dispatch(new BooksActions.Load());
          }
        }),   
    

    一旦您分派 Load 操作,您的 reducer 很可能会将加载的属性设置为 false,重新触发初始选择器,这会再次触发操作的分派。

    在我看来,你需要做的是:

    1. 如果列表已加载,则只检查一次。如果不是,请派遣 行动。否则 NOOP。
    2. 上一步完成后, 等待列表加载并检查一次 实体的存在。

    这可以通过以下方式存档:

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> 
    {
       return concat(this.loadIfRequired(), this.hasBookInStore(route.params['id'])).pipe(skip(1));
    }
    
    private loadIfRequired(): Observable<any>
    {
       return booksState$.pipe(
        map(state => state.loaded),
        take(1),
        tap(loaded=> {
          if (!loaded) {
            this.store.dispatch(new BooksActions.Load());
          }
        }));
    }
    
    private hasBookInStore(id: string): Observable<boolean>
    {
      return this.booksState$.pipe(
        first(state => state.loaded),
        map(state => state.list.find(book => book.id === id)),
        map((book) => {
         if(!!book) return true;
         this.router.navigate(['/404']);
         return false;
       })
      );
    }
    
    private get booksState$(): Observable<BooksState>
    {
     return this.store.pipe(
        select(state => state.books));
    }
    

    如果这有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2011-08-02
      相关资源
      最近更新 更多