我有一个方法可以返回一个用户的角色,比如说。
getUserRoles() : Observable<string[]> {
return this.getToken().pipe(
map(token => {
let payload = decode(token);
return payload["roles"];
})
)
}
我想在一个锚中使用这个方法,根据角色来展示项目,比如:
<a *ngIf="(authService.getUserRoles | async).includes('admin')" routerLink="/admin" clrDropdownItem>Admin</a>
然而,我得到的编译器错误。
ERROR in src/app/components/profile/profile.component.html:15:18 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type '() => Observable<string[]>' is not assignable to parameter of type 'Promise<unknown>'.
Type '() => Observable<string[]>' is missing the following properties from type 'Promise<unknown>': then, catch, [Symbol.toStringTag], finally
15 <a *ngIf="(authService.getUserRoles | async).includes('admin')" routerLink="/admin" clrDropdownItem>Admin</a>
~~~~~~~~~~~~~~~~~~~~~~~~~
src/app/components/profile/profile.component.ts:7:16
7 templateUrl: './profile.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component ProfileComponent.
我不太明白我做错了什么。我使用的是Angular 9。
啊,我想我明白了!
我曾经遇到过一个有点类似的问题,也是模板中的函数调用。长话短说,变化检测触发了变化检测,这或多或少的是 while (true);
.
试着改变这个
<a *ngIf="(authService.getUserRoles() | async).includes('admin')" ...
变成
<a *ngIf="userIsAdmin" ...
而在组件的TS部分
userIsAdmin = false;
onDestroy = new Subject();
ngOnInit() {
this.authService.getUserRoles().pipe(takeUntil(this.onDestroy)).subscribe(/* assign value to this.userIsAdmin here
}
ngOnDestroy() {
/* To prevent a memory leak */
this.onDestroy.next();
this.onDestroy.complete();
}
你的方法是行不通的...
即使你把你的代码改成这样。authService.getUserRoles() | async
你的代码也不会起作用,因为这个函数会在每次检查你的视图时运行,而你不会从这个函数中受益。async
管,反之。
这将是更好的
1)在组件的初始化中订阅你的数据(记得在你销毁组件之前取消订阅)。
2) 创建新的管道来处理该逻辑。
3) 使用 警卫.
4)使函数同步。
.ts
isInRole(role: string): boolean {
const token = this.getToken();
const payload = decode(token);
return payload && payload["roles"] && payload["roles"].includes(role);
}
.html
<a *ngIf="isInRole('admin')" routerLink="/admin" clrDropdownItem>Admin</a>
试试这个概念(未测试)。
getUserRoles() : Observable<string[]> {
let obs = from(this.getToken())
obs.subscribe(pipe(
map(token => {
let payload = decode(token);
return payload["roles"];
}));
return obs;
)
}