从服务返回数据

时间:2020-02-29 07:17:37

标签: angular

我有以下代码,我在其中根据权限生成菜单,我在咨询服务“ this.auth.permissions”,该服务应返回一个值,但无法从应用程序访问它.menu,但是如果我调用observable并为其提供一个控制台,则如果它向我显示数据,但是我不需要observable而是直接数据,可以在“ hasExpectedPermissions”函数中使用它。

app.menu.js

import { AuthService } from './@auth/auth.service';

@Injectable()
export class AppMenu implements OnInit{
  permissions:any=[];
  dashboardMenu: NbMenuItem[] = [];


    constructor(private auth: AuthService){
this.auth.permissions$.subscribe(permi=>{
      console.log("permi",permi)
    })
}

  ngOnInit(){

  }

  getMenu(): Observable<NbMenuItem[]> {
    const dashboardMenu = [
      {
        title: 'Dashboard',
        icon: 'home-outline',
        link: '/',
        home: true,
        children: undefined,
      },
      {
        title: 'Users',
        icon: 'person-outline',
        link: '/users',
        data: ['create:user', 'read:user'],
        children: [
          {
            title: 'Users',
            link: '/users',
            data: ['read:user'],
          },
          {
            title: 'Create User',
            link: '/edit-user',
            data: ['create:user'],
          },
        ],

      },
    ];

    function hasExpectedPermissions(page) {
      let permissionsa = this.auth.permissions;

      for(const data of page.data) {
        console.log("data",data);
        page.enabled = permissionsa.indexOf(data) > -1 || page.enabled;
      }

      return page.enabled;
    }

    function getAllowedPages(pages) {
      return pages.filter(function (page) {
        return (page.data === undefined) || (hasExpectedPermissions(page) === true);
      }).map(page => {
        if (page.children) {
          page.children = getAllowedPages(page.children);
        }
        return page;
      });
    }

      console.log('get', getAllowedPages(dashboardMenu) );




    return of([...dashboardMenu]);
  }
}

auth.service.js

public permissions: string[];
  public permissions$ = new Observable((observer) => {
    this.auth0Client$.subscribe(client => {
      if (client.isAuthenticated()) {
        from(client.getTokenSilently()).subscribe(token => {
          this.tokenSilently$ = token;
          const decodedToken = this.helper.decodeToken(token);
          this.permissions = decodedToken.permissions;
          observer.next(decodedToken.permissions);
        });
      }
    });
  }) as Observable<string[]>;

1 个答案:

答案 0 :(得分:0)

如果您异步获取权限,则需要在服务返回权限后在subscribe的正文中构建菜单。

首先,我重构了您的服务,以在管道中的concatMap中进行链式可观察的调用,而不是使用内部订阅和不必要的Observable包装器。

auth.service.ts

permissions$ = this.auth0Client$.pipe(  
  concatMap(client => client.isAuthenticated() ? from(client.getTokenSilently()) : of(null)),
  map(token => {
    if (!token) {
      return [];
    }

    const decodedToken = this.helper.decodeToken(token);
    return decodedToken.permissions;
  })
);

然后在组件中,您在ngOnInit中(而不是在构造函数中)进行订阅,并在subscribe中构建菜单。我没有包括菜单本身的构建,因为此答案更多地是关于向您显示可观察对象的设置。

app-menu.component.ts

export class AppMenu implements OnInit{
  constructor(private auth: AuthService) {}

  permissions = [];

  ngOnInit(): void {
    this.auth.permissions$.subscribe(permissions => {
      this.permissions = permissions;

      this.buildMenu();
    });
  }

  private buildMenu(): void {
    // TODO: implement
  }
}

我不确定auth0client是什么,但是如果它做的事情比单个http请求更复杂,则需要研究取消订阅的情况。