我有一个名为PermissionGuard
的路由器保护,它在这里启动
const routes: Routes = [
{
path: ':company',
component: CompanyComponent,
canActivate: [PermissionGuard],
canActivateChild: [PermissionGuard],
children: [
{
path: '',
component: IndexComponent
},
{
path: 'projects',
loadChildren: '../projects/projects.module#ProjectsModule'
},
]
}
];
在我的PermissionGuard
中,我订阅了这样的PermissionService
:
export class PermissionGuard implements CanActivate, CanActivateChild {
private permissions: Permission[];
constructor(private permissionService: PermissionService, private router: Router) {
this.permissionService.permissions$.subscribe(
(permissions: Permission[]) => {
this.permissions = permissions;
}
);
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
this.permissionService.getPermissions(next.paramMap.get('company'));
return this.permissionService.permissionsFetchDone$
.pipe(filter(x => x))
.pipe(
map(response => {
if (this.permissions) {
return true;
} else {
this.router.navigate(['/forbidden']);
}
})
);
}
}
并基于该数据执行必要的canActivate
或canActivateChild
检查。通过在子路由中添加console.log()
和从permissions$
发出新数据,我可以看到可观察值仍然是活动的,即使守卫已经“使用”并且路由已被激活。然后,我希望当我到path: ':company'
外的一条路线时,它会消失,但是这个守卫并没有被摧毁。
这就引出了我的问题:,我这样做正确吗?我希望使用保护来检查用户是否有任何权限,但同时我希望只执行一次权限的HTTP请求(当导航到path: ':company'
或其任何子项时)。我担心,如果我使用这样的守卫,由于大量的观察者,最终会减慢整个应用程序的运行速度。
发布于 2018-10-23 03:39:39
从子路由内的权限$发出新数据我可以看到,即使守卫已被“使用”并且路由已被激活,但可观察性仍然是活动的。
首先,permissions$
仍然是活动的,因为你从来没有在你的守卫中取消订阅。并且angular创建了一个单例的守卫。
即使guard不是单例的,guard的实例仍然通过this.permissions
在订阅中被引用,并且如果您的observable作为变量存在于您的身份验证服务中(我假设它是一个单例),此绑定也会阻止垃圾收集。
这就引出了我的问题:我这样做正确吗?我希望使用守卫来检查用户是否有权限。
在你的守卫下发出一个请求是完全没问题的,比如为了获得权限。
,但同时我只想执行一次权限的HTTP请求(当导航到path:':company‘或它的任何子级时)。
如果您只想发出一次请求,那么您应该考虑在身份验证服务中使用shareReplay,以便将来连接的所有实例都使用先前发出的相同值。
https://stackoverflow.com/questions/52936191
复制相似问题