在路由解析器中使用订阅

时间:2019-10-23 16:43:02

标签: angular rxjs angular2-routing

我想向服务询问一些数据,以允许路由解析器采取特定措施。

应该由服务返回的数据,不是解析路由后组件将使用的数据,这是解析器的明确用法,它说明了解析器为什么必须返回Observable的原因。

我真正需要服务返回的数据的目的是在根本解决路由之前决定几种可能的操作之间。

我为什么会遇到这种情况?

我遇到的情况是,带有slug参数的顶部url可能需要呈现不同的组件。

示例

  

example.com/whatever-post-slug->需要加载PostComponent
  example.com/other-page-slug->需要加载PageComponent
  example.com/new-slug-for-random-post->需要加载PostComponent
  ...

为什么我不只是给路线加上前缀?

因为我不能。我正在为WordPress创建主题,并为帖子和页面提供类似的网址。有关更多详细信息,请参见this question

我的解析器实际上在做什么?

我只会显示部分代码,以使其易于理解:

resolve(route: ActivatedRouteSnapshot): Observable<any>|any{
   this.wprestNoAuthSrv.getPermalinkStructure()
       .pipe(takeUntil(this.unsubscribeOnDestroy))
       .subscribe(
       // ... check httpResponse and decide where to go
          this.router.navigate(route, { skipLocationChange: true });
       )
}

由于我正在解析器内进行预订,因此与要解析的路线相关联的组件会在进行Navigation()之前加载。

这会导致非常难看的导航效果。

问题是

在仍使用该订阅的同时如何阻止这种情况发生?

我实际上希望该组件永远不要加载,因为总会出现navigate()

如果您意识到,我将{ skipLocationChange: true }放入router.navigate(),因为我希望用户将路径保留在浏览器中。

我了解这似乎是在滥用Angular的路由系统,但我想实现这一结果。

这个问题与我要动态加载不同组件的事实有关(为此,我发布了上述链接的问题)。

这个问题是关于选择的方法的,这种方法是可行的,但是有一个我想避免的缺点。

可行的想法

这个想法可行,但是也许您知道更好的解决方案。如果我创建了一个Observabe并通过resolve()方法将其返回,则可以强制解析器等待,并在完成时进行重定向。

return Observable.create(observer => {
  setTimeout(() => {
    observer.next("Finished");
    observer.complete();
  }, 5000);
});

当然,这是一个大谎言,不是很好。即使它运行完美,我也需要知道这是一件很不好的事情,还是有更好的选择。

1 个答案:

答案 0 :(得分:3)

看起来像您在尝试在解析器中重定向并在Observable中进行订阅绝不是一个好主意。这应该符合您的期望:

resolve(route: ActivatedRouteSnapshot): Observable<any>|any{
   return this.wprestNoAuthSrv.getPermalinkStructure().pipe(
     takeUntil(this.unsubscribeOnDestroy),
     mergeMap(httpResponse => {
       // ... check httpResponse and decide where to go
       this.router.navigate(route, { skipLocationChange: true });
       return EMPTY;
     })
   );
}