依赖注入错误随导航流程而变化(延迟加载的Angular模块)

时间:2017-04-09 10:41:42

标签: javascript angular typescript dependency-injection

我在Webpack AoT设置中使用@angular ^4.0.1,大量使用延迟加载的模块。但我开始看到依赖注入错误,我无法找到它的来源。基本上,依赖关系在某些导航流中工作正常,但在其他导航流中则不行。

这是一个具体的例子:

App组件延迟加载Level1

{path: 'level1', loadChildren: './+level1#Level1Module'},

并采用相同的路线样式,Level1Level2,拉Level3

这些是基本组件,在此上下文中主要提供HTML模板。

Level3是出错的地方,因为我在Level3Service的提供商中声明了一个简单的Level3Module

@NgModule({
  declarations: [
    Level3Component,
  ],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    RouterModule.forChild(routes),
    SharedModule,
  ],
  providers: [
    Level3Service,
  ]
})
export class Level3Module {
  public static routes = routes;
}

现在,Level3有两个延迟加载的孩子,Level3ChildALevel3ChildB。儿童路线看起来有点不同,因为他们自己没有孩子,他们是实际页面:

{path: '', component: Level3ChildXComponent, pathMatch: 'full'},

我也不会重新宣布Level3Service,虽然我会需要它。根据我的理解,如果我重新声明提供者,它将不再是共享实例,而是新实例。

@NgModule({
  declarations: [
    Level3ChildXComponent,
  ],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    RouterModule.forChild(routes),
    SharedModule,
  ],
  providers: [
      // Level3Service, // Let's not redeclare this, we want a shared instance.
      Level3ChildXSomeService,
  ]
})
export class Level3ChildXModule {
  public static routes = routes;
}

Level3ChildA开始,用户与表单进行交互,bla bla,然后我想将用户从 A 移动到 B ,{{ 1}}。我是从Level3ChildB

执行此操作的
Level3ChildAComponent

这是旅程以错误和其中一个疯狂的长堆栈结束的地方。

this.level3Service.doSomething();
return this.router.navigate(['../B'], { relativeTo: this.route.parent });

我希望有人能帮我理解这里发生的事情。

似乎一般规则是,如果我从一开始就重新加载应用程序,所有依赖提供程序都可以工作。但是,如果我打开一个新的浏览器,直接导航到其中一个子页面(例如 A 页面),那么它就不会从父模块ERROR Error: Uncaught (in promise): Error: No provider for Level3Service! Error at injectionError (http://localhost:3000/vendor.dll.js:2579:86) [angular] at noProviderError (http://localhost:3000/vendor.dll.js:2617:12) [angular] at ReflectiveInjector_._throwOrNull (http://localhost:3000/vendor.dll.js:4118:19) [angular] at ReflectiveInjector_._getByKeyDefault (http://localhost:3000/vendor.dll.js:4157:25) [angular] at ReflectiveInjector_._getByKey (http://localhost:3000/vendor.dll.js:4089:25) [angular] at ReflectiveInjector_.get (http://localhost:3000/vendor.dll.js:3958:21) [angular] at AppModuleInjector.NgModuleInjector.get (http://localhost:3000/vendor.dll.js:4905:52) [angular] at Level3ChildBModuleInjector.NgModuleInjector.get (http://localhost:3000/vendor.dll.js:4905:52) [angular] (...) hundred lines omitted. 了解该提供程序。

更新

我发现当从子模块Level3中删除providers数组时,此错误会停止重现。那些是看似无关的提供者,但在某些情况下,就好像它们从父模块覆盖了提供者堆栈一样!

1 个答案:

答案 0 :(得分:0)

通过将角度包从^4.0.1更新为^4.0.2,似乎可以解决问题。

可能是编译器错误修正(#15583)。 https://github.com/angular/angular/blob/master/CHANGELOG.md