我正在寻找解决我的项目问题的方法。我有 http 调用来获取userPermissions
,我有两个地方使用它:
- 路径上的身份验证守卫
- 组件模板中的指令
有一种情况同时发生(使用 auth guard 加载带有指令的子组件的路由),我正在寻找一种解决方案,如果需要,只进行一次 http 调用,而不是为每个调用。没有redux,有什么“简单”的方法吗?
您可以在下面找到示例代码,它并不完全相同,但可以让您了解我正在尝试做什么。
用户服务.ts
export class UserService {
userPermissions: string[];
constructor(private userApi: UserApi) {}
getUserPermissions(): Promise<string[]> {
return new Promise((resolve, reject) => {
if (this.userPermissions) {
resolve(this.userPermissions);
} else {
this.userApi.getCurrentUser()
.subscribe((user) => {
this.userPermissions = user.permissions;
resolve(this.userPermission);
}, (err) => {
reject(err);
});
}
});
}
}
一些.component.ts
@Component({
template: `
<div appAuth [roles]="['read', 'write']" #myAuth="appAuth"
*ngIf="myAuth.hasAllRoles()">...</div>
`
})
auth.directive.ts
@Directive({
selector: 'appAuth'
})
export class AppAuth {
@Input() roles: string[];
constructor(private userService: UserService) {}
async hasAllRoles() {
const userPermissions = await this.userService.getUserPermissions();
let guard = true;
this.roles.forEach(role => {
if (this.userPermissions.indexOf(role) === -1) {
guard = false;
break;
}
});
return guard;
}
}
app.module.ts
@NgModule({
imports: [
RouterModule.forRoot([
{ path: 'my-component', canActivate: [AuthGuard], data: { roles: ['write'] }, component: MyComponent }
])
]
})
export class AppModule {}
auth.guard.ts
export class AuthGuard implements CanActivate {
constructor(private userService: UserService) {}
canActivate(route: ActivatedRouteSnapshot) {
return new Promise((resolve, reject) => {
this.userService.getUserPermissions()
.then(((userPermissions: string[]) => {
if (route.data.roles) {
let guard = true;
route.data.roles.forEach(role => {
if (userPermissions.indexOf(role) === -1) {
guard = false;
break;
}
});
resolve(guard);
} else {
resolve(true);
}
});
})
}
}