对于实体的受保护视图,我使用了一个 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),
);
}
因此有两个问题。
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),
);
}
@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。