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

Reload ngrx state data every time RouteGuard is activated

对于实体的受保护视图,我使用 RouteGuard 将所需视图所需的数据预加载到 ngrx 存储中。但是,来自后端的相应数据会随时间变化。因此,每次路由被激活时,store 的旧状态应该被来自后端的新数据覆盖,如果有的话。只有当新数据已经加载到存储中并且完全可用时,路由才应该被激活。可能是后台删除了实体

为此,我有以下最小示例:Stackblitz Example

在当前的实现中,每次调用路由时都会调用操作 GetEntity(),从后端加载数据。但是路由仍然是根据商店以前的状态激活的,这不是我们想要的行为。应该以某种方式使旧状态无效或删除,以便无法激活路由。
这是RouteGuardcanActivate函数的逻辑:

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 是否是实现这种从后端重新加载逻辑的正确位置,或者是否需要进一步调整状态或效果?
  1. 方法是在你的守卫启动时添加标志,数据应该被刷新,只有当它被刷新时才发出。
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.com/articles/understanding-angular-route-resolvers-by-example