每次激活RouteGuard时重新加载ngrx状态数据。

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

对于实体的受保护视图,我使用了一个 RouteGuard 来将所需视图的数据预加载到ngrx存储中。但是,后台的数据可能会随着时间的推移而改变,因此,每次激活途径时,都要用后台的新数据覆盖存储的旧状态。因此,每次激活途径时,都要用来自后台的新数据(如果有的话)覆盖存储的旧状态。只有当新的数据已经加载到存储中,并且完全可以使用时,路由才应该被激活。这可能是在这期间实体已经在后台被删除了。

为此,我有以下最小的例子。Stackblitz示例

在目前的执行中,行动 GetEntity() 是在每次调用路由时调用的,它从后台加载数据。但是路由仍然是基于存储的以前的状态来激活的,这不是我们想要的行为。旧的状态应该以某种方式失效或删除,才能不激活路由。下面是这样的逻辑 canActivate 的作用 RouteGuard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.pipe(select(selectEntityMap)).pipe(
      map(taskMap => Object.keys(taskMap).length > 0),
      tap(loaded => {
        this.store.dispatch(GetEntity()); // trigger backend loading
      }),
      filter(loaded => !!loaded), // waiting until the enties has been loaded.
      take(1),
    );
  }

因此有两个问题。

  1. 如何改变RouteGuard,使其在每次启动时从后端加载数据,并仅以新加载的数据启动路线?
  2. RouteGuard是实现这种从后端重新加载的逻辑的正确位置,还是需要进一步调整状态或效果?
angular typescript angular2-routing ngrx ngrx-store
1个回答
1
投票
  1. 方法是在你的Guard启动时添加标志,说明数据应该被刷新,并且只有当数据被刷新时才会发出。
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // it should reset `taskMap` to undefined.
    // initial value of taskMap has to be null (anything but not undefined).
    this.store.dispatch(GetEntity());

    return this.store.pipe(select(selectEntityMap)).pipe(
      skipWhile(taskMap => taskMap !== undefined), // waiting until start
      skipWhile(taskMap => taskMap === undefined), // waiting until end

      take(1),
      map(taskMap => taskMap !== null),
    );
  }
  1. 正确的地方是一个解析器
@Injectable({
providedIn: 'root'
})
export class UserResolverService implements Resolve<any> {
  constructor(private fakeApi: FakeApiService) { }
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.fakeApi.getUsers().pipe(
      catchError((error) => {
      return empty();
      });
    );
  }
}

你可以在这里阅读更多信息。https:/dzone.comarticlesunderstanding-angular-route-resolvers by-example。

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