【发布时间】:2021-01-20 20:43:09
【问题描述】:
我已经构建了一个用户权限服务,该服务从服务器获取给定用户的权限。我进一步构建了一个路由守卫,它利用此服务来确定用户是否具有路由中列出的所有权限。为此,我遍历路由上列出的权限,并在查询用户权限服务时为每个权限创建一个 observable。一旦所有的 observables 被创建,我forkJoin 确保它们都是真实的。
在我对权限服务的一般测试中,我每次都能可靠地返回结果。如果我手动迭代返回的数组并手动订阅每个 observable,它会按需要工作。但是,无论我做什么,forkJoin 似乎都不会执行。如果我用 [of(true),of(true)] 的数组替换我生成的 observables,它会按预期运行。我不太清楚发生了什么。
用户服务:
@Injectable({
providedIn: 'root'
})
export class UserPermissionsService {
private _permissions = new BehaviorSubject<AppliedPermissions>(null);
public permissionSnapshot: AppliedPermissions;
public permissions: Observable<AppliedPermissions> = this._permissions.asObservable();
constructor(private _userService: UserService) {
}
init(): Observable<AppliedPermissions> {
return this._userService.getPermissions()
.pipe(tap(p => {
this._permissions.next(p)
this.permissionSnapshot = p;
}));
}
destroy(): void {
this._permissions?.complete();
}
hasPermission(permission: string): Observable<boolean> {
return this._permissions.pipe(
switchMap(value => value ? of(value) : this.init()),
map(response => {
const perm = response.permissions
.find(el => el.permissionName === permission);
if (!perm)
return false;
return perm.allow;
}),
catchError(_ => of(false))
);
}
inRole(role: string): Observable<boolean> {
return this._permissions.pipe(
switchMap(value => value ? of(value) : this.init()),
map(response => {
return !!response.roles.find(el => el === role);
}),
catchError(_ => of(false))
);
}
}
路线守卫
@Injectable({providedIn: 'root'})
export class PermissionGuard implements CanActivate {
constructor(private _userPermissionsService: UserPermissionsService) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
const permissions = route.data.permissions as Array<string>;
const observables = permissions.map(p => this._userPermissionsService.hasPermission(p));
return forkJoin(observables)
.pipe(
tap(e => {
console.log(e)
}),
map(e => e.every(v => v)),
catchError(_ => of(false))
);
}
}
【问题讨论】:
标签: angular typescript rxjs