ngIf指令中的Observable<string[]>。

问题描述 投票:0回答:1

我有一个方法可以返回一个用户的角色,比如说。

  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。

angular angular-ng-if rxjs-observables
1个回答
2
投票

啊,我想我明白了!

我曾经遇到过一个有点类似的问题,也是模板中的函数调用。长话短说,变化检测触发了变化检测,这或多或少的是 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();
}

1
投票

你的方法是行不通的...

即使你把你的代码改成这样。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>

0
投票

试试这个概念(未测试)。

getUserRoles() : Observable<string[]> {
      let obs = from(this.getToken())
      obs.subscribe(pipe(
      map(token => {
        let payload = decode(token);
        return payload["roles"];
      }));
      return obs;
    )
  }
© www.soinside.com 2019 - 2024. All rights reserved.