【问题标题】:Angular 5 Observable need to wait until it's comlpeteAngular 5 Observable 需要等到它完成
【发布时间】:2018-12-20 00:38:32
【问题描述】:

在调用 checkPermissions() 方法之前,我需要等到 getPermissions() observable 完成。但是对于我的生活,我无法得到它......

我也尝试过使用 async/await,但这似乎对我也不起作用?

我需要获得我的权限,然后才能检查它们,对吧。想法?

如果有更好的方法,我会全力以赴。

非常感谢。

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class RoleGuardService implements CanActivate {
  
  constructor(public auth: AuthService,public router: Router) { }

  canActivate(route: ActivatedRouteSnapshot): boolean {
    //This will be passed from the route config, on the data property
    const expectedRole = route.data.expectedRole;
    var hasPerm = this.loadAndCheckPermissions(expectedRole);

    console.log('done! ' + hasPerm);
    return hasPerm;
  }

  loadAndCheckPermissions(expectedRole) {
    var hasPermission = false;
    localStorage.clear();
    var myPermissions = localStorage.getItem('user-permissions');
    
    if (myPermissions === null) {
      console.log("PERMISSIONS from Server!");

      //You can't wait for an Observable or Promise to complete.
      //You can only subscribe to it to get notified when it completes or emits an event.
      this.auth.getPermissions()
        .subscribe(res => {
          localStorage.setItem('user-permissions', JSON.stringify(res.body));

          //Check permissions now
          //hasPermission = this.checkPermissions(expectedRole);
        });
    } else {
      hasPermission = this.checkPermissions(expectedRole); 
    }

    console.log('loadAndCheckPermissions ' + hasPermission);
    return hasPermission;
  }

  //Check a permission here
  checkPermissions(expectedRole) {
    return this.auth.checkPermission(expectedRole);
  }
}

【问题讨论】:

  • loadAndCheckPermissions 应该是可观察的,与canActivate 相同。如果你有更高的函数依赖于它们返回的内容,你要么需要组合函数,要么继续将子函数声明为 observables

标签: angular observable


【解决方案1】:

你可以在你的 canActivate 方法中返回一个 Observable,就像这样:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class RoleGuardService implements CanActivate {

  constructor(
    public auth: AuthService,
    public router: Router
  ) { }

  canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {

    //This will be passed from the route config, on the data property
    const expectedRole = route.data.expectedRole;

    var hasPerm = this.loadAndCheckPermissions(expectedRole);

    console.log('done! ' + hasPerm);
    return hasPerm;
  }

  loadAndCheckPermissions(expectedRole):  Observable<boolean> {

    var hasPermission: Observable<boolean> = Observable.of(false);

    //clear
    localStorage.clear();

    //getter
    var myPermissions = localStorage.getItem('user-permissions');
    //
    if (myPermissions === null) {

      console.log("PERMISSIONS from Server!");

       hasPermission = this.auth.getPermissions()
        .map(res => {
          localStorage.setItem('user-permissions', JSON.stringify(res.body));
          console.log('return from async');

          // Check permissions RETURNING A BOOLEAN
          return this.checkPermissions(expectedRole);
        });

    }
    else {
      hasPermission = Obsersable.of(this.checkPermissions(expectedRole)); 
    }

   // console.log('loadAndCheckPermissions ' + hasPermission);
    return hasPermission;
  }

  //Check a permission here
  checkPermissions(expectedRole) {
    return this.auth.checkPermission(expectedRole);
  }


}

根据 Angular 的文档,路由守卫可以返回 Observable 或 Promise,路由器将等待 observable 解析为 true 或 false。

https://angular.io/guide/router#milestone-5-route-guards

【讨论】:

  • 我认为打Observable&lt;boolean&gt; 不会解决问题。您需要声明一个observer 并使用observer.next() 返回值,如示例here
  • 这些例子没有使用 Angular API 的 Observable,也没有 next 方法。
  • 这也不起作用! loadAndCheckPermissions console.log() 在异步调用完成之前返回。
  • 为什么需要等待异步调用?如果你只想实现一个 canActivate 守卫,它可以作为异步调用的结果返回一个 Observable,因为路由器将等待 observable 解析为 true 或 false。在 Observable(异步调用)完成之前,不会激活路由。
  • 马克,看到这个答案:stackoverflow.com/questions/37948068/…
猜你喜欢
  • 2018-09-18
  • 2020-11-05
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
相关资源
最近更新 更多