即使已加载数据,未定义选定的角度ngrx保护]]

问题描述 投票:1回答:1

我有这个减速器

on(CmsActions.loadCmsTopNewsSelected, (state, { slug }) => {
    let selected;
    if (state.data) {
      selected = state.data.items.find(item => item.data.slug.iv === slug);
    }
    return {
      ...state,
      selected
    };
  })

和这个后卫

canActivate(route: ActivatedRouteSnapshot): Observable<boolean | UrlTree> {
    return this.checkStore().pipe(
      switchMap(() => {
        const slug = route.params.slug;
        this.facade.selected(slug);
        return this.facade.selected$.pipe(
          map(selected => {
            console.log('selected', selected);
            if (selected) {
              return true;
            }
            return this.router.parseUrl('/not-found');
          })
        );
      }),
      catchError(() => of(false))
    );
  }

  checkStore(): Observable<boolean> {
    return this.facade.loaded$.pipe(
      tap(loaded => {
        if (!loaded) {
          this.facade.load(this.ITEMS_TO_LOAD);
        }
      }),
      filter(loaded => {
        console.log('loaded', loaded);
        return loaded;
      }),
      take(1)
    );
  }

如果我通过路由器链接转到路线,效果很好,

但是如果我直接去,则所选择的是不确定的,即使

数据已加载。

怎么了?

更新

为了更好的理解,我发布了更多代码顺便说一句,我正在等待加载数据当子路由正在由浏览器运行时。

路线父母

{
   path: 'news',
   canLoad: [CmsNewsGuard],
   loadChildren: () =>
          import('./news/news.module').then(m => m.PublicNewsModule)
},

儿童

{
    path: ':slug',
    canActivate: [CmsNewsGuardSelected],
    component: PublicNewsPageDetailsComponent
  },
  {
    path: '',
    component: PublicNewsListComponent,
    pathMatch: 'full'
  }

外观

export class CmsNewsFacade {
  get data$(): Observable<CmsArray<CmsNews> | null> {
    return this.store.pipe(select(selectCmsNewsData));
  }

  get error$(): Observable<Required<ErrorDto> | null> {
    return this.store.pipe(select(selectCmsNewsError));
  }

  get loaded$(): Observable<boolean> {
    return this.store.pipe(select(selectCmsNewsLoaded));
  }

  get selected$(): Observable<CmsNews | undefined> {
    return this.store.pipe(select(selectCmsNewsSelected));
  }

  constructor(private store: Store<CmsState>) {}

  load(top: number): void {
    this.store.dispatch(CmsActions.loadCmsTopNews({ top }));
  }

  selected(slug: string): void {
    this.store.dispatch(CmsActions.loadCmsTopNewsSelected({ slug }));
  }
}

选择器

export const selectCmsNewsSelected = createSelector(
  selectMarketAccountFeature,
  (state: CmsState) => {
    return state.news.selected;
  }
);

UPDATE2

它起作用

return this.facade.selected$.pipe(
          filter(selected => {
            return !!selected;
          }),
          map(selected => {
            if (selected) {
              return true;
            }
            return this.router.parseUrl('/not-found');
          })
        );

但是这样做我失去了目标,显示未找到的页面如果子弹不存在:(

我已经在(CmsActions.loadCmsTopNewsSelected,(state,{slug})=> { .slug.iv === ...

angular ngrx angular-router-guards
1个回答
1
投票

我认为您的选择器会尝试选择一个未定义的状态,因为加载页面时,Guard会比加载后存储在存储中的数据外观更快地检查条件。这是因为延迟加载。预先加载的模块中提供了您的Guard。您的商店商品是在延迟加载的模块中声明的,这就是为什么您的Guard在第一次加载时不接受导航的问题。

© www.soinside.com 2019 - 2024. All rights reserved.