Route Guard加载ngrx存储数据仅在第二次单击后导航到受保护的路由

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

要在加载实际组件之前将数据从后端加载到我的ngrx存储中,我在路由的canActivate属性中使用了路由保护。

{path: 'my-route', component: MyRouteComponent, canActivate: [LoadDataGuardService]}

警卫队应在商店中检查相应的数据是否已经可用。如果没有,则应将其从后端加载到商店中。一旦数据存储在商店中,就应该打开路线(首先单击并单击)。这是我的Guard的canActivate方法。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const loadedTasks = this.store.pipe(select(selectTaskMap))
      .pipe(map(taskMap => Object.keys(taskMap).length > 0));

    loadedTasks
      .pipe(
        take(1),
        filter(loaded => !loaded),
        map(() => this.store.dispatch(GetTasks())))
      .subscribe(() => this.store);

    return loadedTasks
      .pipe(take(1));
  }

首先将数据加载到存储中就可以了。但是,如果必须加载数据,则必须再次单击链接以导航到所需的视图。似乎第一次单击仅加载了数据,但在成功加载数据后没有返回Observable的True

我如何调整代码以将数据加载到商店中,并在第一次单击时将数据加载到商店中后立即打开路线?

编辑:

这里是关于堆叠闪电战的再现实例:Stackblitz Link您可以清楚地看到,第二次单击Activate Route链接后,才显示路线组件的内容。为了在测试时清除商店,我添加了一个按钮。

angular rxjs angular2-routing ngrx
1个回答
0
投票

看起来好像是第一次尚未加载任务。

尝试在first之后移动filter

import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {Store, select } from '@ngrx/store';
import {filter, tap, map, take} from 'rxjs/operators';
import { selectEntityMap } from './store/selectors/entity.selectors';
import { AppState } from './store/state/app.state';
import { GetEntity } from './store/actions/entity.actions';

@Injectable({
  providedIn: 'root'
})
export class LoadDataGuardService implements CanActivate {

  constructor(public router: Router, private store: Store<AppState>) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.pipe(select(selectEntityMap)).pipe(
      map(taskMap => Object.keys(taskMap).length > 0),
       tap(loaded => {
        if (!loaded) { // checking if we need to dispatch the action.
          this.store.dispatch(GetEntity());
        }
      }),
      filter(loaded => !!loaded), // waiting until the tasks have been loaded.
      take(1),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.