【问题标题】:Issue with route resolver路由解析器的问题
【发布时间】:2026-01-21 10:35:01
【问题描述】:

我有一个带有解析器的延迟加载路由:

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: '',
        component: MyComponent,
        resolve: {
          data: MyService
        }
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class MyRoutingModule {}

我的模块

@NgModule({
  imports: [
    CommonModule,
    MyRoutingModule,
    ...
  ],
  declarations: [
    MyComponent,
    ...
  ],
  providers: [MyService]
})
export class MyModule {}

我的服务resolver

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
    return forkJoin(
      this.getData1(),
      this.getData2(),
      this.getData3()
    );
  }

我正在订阅我的应用组件上的属性data

export class AppComponent implements OnInit {
  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.data.subscribe(x => {
      data = x; //x = undefined
    });
  }
}

问题是x 总是undefined
任何想法为什么我无法访问已解析的数据以及如何解决这个问题?

更新: 我想知道数据何时解析,所以我想隐藏微调器。 根据@OneLunch-Man 的帖子,我的应用程序组件将无法访问该数据,那么您将如何解决这个问题,我需要在我的应用程序组件上知道的只是数据何时被解析,以便我可以做一些 UI 状态隐藏微调器等更改

【问题讨论】:

  • 问:你到底想要完成什么?
  • @paulsm4 我不知道数据何时解析,所以我想隐藏微调器。
  • 问:你能利用 Angular 生命周期事件来完成这个吗?

标签: angular angular-router


【解决方案1】:

AppComponent 位于路由器出口之外,无权访问此数据。 只有路由的子组件才能访问它。

【讨论】:

  • 有没有办法在应用程序组件上知道数据已被解析?我不知道数据何时解析,所以我想隐藏微调器。
  • 就我个人而言,我将微调器保留在子组件中。有很多选择,但没有一种“固定方式”可以做到这一点,而且我不是全局加载器的忠实粉丝,而不是本地化加载器(观点)。 - 一种方法是您可以拥有一个带有主题/可观察对象的服务,当数据在子节点上解析时,点击服务方法来更改主题(这将触发可观察对象隐藏微调器)。
  • 是的,刚刚将其实现为服务。顺便说一句,为什么router-outlet 无法访问这些数据?
  • 哦,当然。所以包含 router-outlet 的组件(通常是 app 组件)已经构建好了。当您导航时,包含的组件不会重新构建,router-outlet 中的内容会更改为路径中的新组件。因此,路由中声明的那些组件可以访问(我相信在)路由器出口级别(包含组件下方)提供的 ActivatedRoute。这是因为此时它们被重构并且它们的依赖被注入。
  • 您实际上可能能够绑定到路由器出口上的事件:angular.io/api/router/RouterOutlet 必须查一下。在您的应用程序组件中,您可以将解析器更改为 promiseAll,将这些可观察对象转换为承诺,并使用路由器出口上的 activate 事件来触发应用程序组件中的函数
【解决方案2】:

您可以使用路由器事件隐藏和显示微调器。而且 routerEvent 也有一个 ResolveStart 和 ResolveEnd 实例,根据您的需要使用它

constructor(private router: Router) {
    router.events.subscribe((routerEvent: Event) => {
      if (routerEvent instanceof NavigationStart) {
      this.loading = true;
    }
    if (routerEvent instanceof NavigationEnd ||
        routerEvent instanceof NavigationCancel ||
        routerEvent instanceof NavigationError) {
      this.loading = false;
    }
    });
  }

参考:https://angular.io/api/router/RouterEvent#subclasses

【讨论】: