[英]Route Guard loading ngrx store data only navigates to protected route after second click
为了在加载实际组件之前将数据从后端加载到我的 ngrx 存储中,我在路由的canActivate
属性中使用了路由保护。
{path: 'my-route', component: MyRouteComponent, canActivate: [LoadDataGuardService]}
如果相应的数据已经可用,Guard 应该检查存储。 如果没有,它应该从后端加载到存储中。 一旦数据在存储中,应该打开路径(第一次,初始点击)。 这是我的 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));
}
第一次点击就可以将数据加载到商店中。 但是,如果必须加载数据,我必须再次单击链接才能导航到所需的视图。 似乎第一次单击只加载数据,但在成功加载数据后没有返回True
的 Observable。
如何调整代码以将数据加载到存储中并在第一次单击时将数据加载到存储中后立即打开路线?
编辑:
这是一个关于用于复制的 stackblitz 的工作示例: Stackblitz Link
您可以清楚地看到,路由组件的内容只是在第二次单击Activate Route
链接后显示。
为了在测试时清除商店,我添加了一个按钮。
看起来问题是第一次还没有加载任务。
尝试在filter
之后first
移动。
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),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.