首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Observable<Observable<T>>到Observable<T>

Observable<Observable<T>>到Observable<T>
EN

Stack Overflow用户
提问于 2019-04-03 00:41:00
回答 1查看 2.2K关注 0票数 7

这里是RxJS初学者。我正在使用角6,并试图找出如何从Observable<T>Observable<Observable<T>>。我不确定这是否有效,我很难从概念上理解它,然而这似乎是一个简单的问题。

我研究过switchMap,flatMap,forJoin,但是我认为它们不适合我的需要。

我试图做的是一个角度路由保护,这将阻止用户访问一个路由,除非他们有必要的权限。2依赖项是一个用户配置文件,用于获取他们的信息,然后用于获取他们的权限。这种混合导致了可观察到的问题。我要说的是:

代码语言:javascript
复制
export class AuthPermissionsRouteGuard implements CanActivate {
    constructor(
    private router: Router,
    private authService: AuthPermissionsService,
    private openIdService: AuthOpenIdService) {}
    
    /**Navigates to route if user has necessary permission, navigates to '/forbidden' otherwise */
    canActivate(routeSnapshot: ActivatedRouteSnapshot): Observable<boolean> {
        return this.canNavigateToRoute(routeSnapshot.data['permissionId'] as number);
    }

    /**Waits on a valid user profile, once we get one - checks permissions */
    private canNavigateToRoute(permissionId: number): Observable<boolean> {
        const observableOfObservable = this.openIdService.$userProfile
            .pipe(
                filter(userProfile => userProfile ? true : false),
                map(_ => this.hasPermissionObservable(permissionId)));

            // Type Observable<Observable<T>> is not assignable to Observable<T> :(
        return observableOfObservable;
    }

    /**Checks if user has permission to access desired route and returns the result. Navigates to '/forbidden' if no permissions */
    private hasPermissionObservable(permissionId: number): Observable<boolean> {
        return this.permissionsService.hasPermission(permissionId).pipe(
            map(hasPermission => {
                if (!hasPermission) {
                    this.router.navigate(['/forbidden']);
                }

                return hasPermission;
            }
        ));
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-03 01:04:50

现在,您将从hasPermissionObservable函数返回一个可观测的,该函数将被包装在一个可从map operator中观察到的函数中。

您将需要查看mergeMap/flatMap operatorcontactMap operator

MergeMap:当您希望将内部可观察到的内容扁平化时,最好使用此操作符,但希望手动控制内部订阅的数量。来自Learn链接的示例:

代码语言:javascript
复制
// RxJS v6+
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

// emit 'Hello'
const source = of('Hello');
// map to inner observable and flatten
const example = source.pipe(mergeMap(val => of(`${val} World!`)));
// output: 'Hello World!'
const subscribe = example.subscribe(val => console.log(val));

ContactMap:按顺序将值映射到内部可观测、订阅和发出。来自Learn链接的示例:

代码语言:javascript
复制
// RxJS v6+
import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';

// emit 'Hello' and 'Goodbye'
const source = of('Hello', 'Goodbye');
// example with promise
const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
// map value from source into inner observable, when complete emit result and move to next
const example = source.pipe(concatMap(val => examplePromise(val)));
// output: 'Example w/ Promise: 'Hello World', Example w/ Promise: 'Goodbye World'
const subscribe = example.subscribe(val =>
  console.log('Example w/ Promise:', val)
);

因此,对于你的例子:

代码语言:javascript
复制
/**Waits on a valid user profile, once we get one - checks permissions */
private canNavigateToRoute(permissionId: number): Observable<boolean> {
  const observableOfObservable = this.openIdService.$userProfile
    .pipe(
       filter(userProfile => userProfile ? true : false),
       concatMap(_ => this.hasPermissionObservable(permissionId))); // <- try changes here

  // Type Observable<Observable<T>> is not assignable to Observable<T> :(
  return observableOfObservable;
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55485409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档