Angular 角度6提供在不';t工作->;静态注入错误

Angular 角度6提供在不';t工作->;静态注入错误,angular,Angular,我试图在Angular中使用'providedin'功能,但收到错误“StaticInjectorError(AppModule)[仪表板组件->仪表板服务]:” 完整演示 谢谢你的努力 我终于找到了解决方案: 服务也应该在模块的提供者部分提及 @NgModule({ imports: [CommonModule], declarations: [DashboardComponent], exports: [DashboardComponent], providers: [Das

我试图在Angular中使用'providedin'功能,但收到错误“StaticInjectorError(AppModule)[仪表板组件->仪表板服务]:”

完整演示
谢谢你的努力

我终于找到了解决方案: 服务也应该在模块的提供者部分提及

@NgModule({
  imports: [CommonModule],
  declarations: [DashboardComponent],
  exports: [DashboardComponent],
  providers: [DashboardService]
})
已更正。 谢谢你们

使用时,Stepan Suvorov发布的消息不起作用

providedIn: AppModule
由于依赖关系问题,导致
AppModule
无法解决(未定义)

如果在
@Injectable
装饰器的正上方添加
console.log(AppModule)
,则输出为
未定义

注意 实际上,您无法在stackblitz上看到该依赖项问题,但如果您在本地cli上复制该项目,您将看到以下警告

检测到循环依赖项中的警告: src\app\app.component.ts->src\app\my.service.ts->src\app\app.module.ts->src\app\app.component.ts

检测到循环依赖项中的警告: src\app\app.module.ts->src\app\app.component.ts->src\app\my.service.ts->src\app\app.module.ts

检测到循环依赖项中的警告: src\app\my.service.ts->src\app\app.module.ts->src\app\app.component.ts->src\app\my.service.ts

我认为在
providedIn
中使用
AppModule
没有任何意义,您也可以使用
root
。但是,如果您希望您的服务只在子模块中提供,那么应该像这样工作

这是一个

注意:在声明可注入服务时,如果使用
中提供的带有模块值的
,则指定的模块不能是声明使用该服务的组件的模块(相当多)

  • 98%的时间使用providedIn='root'。它将向根应用程序注入器注册服务,将被树震动,并可用于任何需要它的组件。摇树将确保该服务仅包含在使用该服务的捆绑包中
  • 如果只需要在组件及其嵌套子级中提供服务,请在组件中使用providers数组。(用于组件级别的服务隔离,或者如果每个组件需要多个服务实例。)
  • 不要在模块中使用providers数组(这是旧语法,不再推荐)
  • 如果要将对服务的访问限制为特定的延迟加载模块,请使用providedIn='lazymodule'。然后,它将需要一个额外的模块来防止循环依赖性问题。这在模块级别提供了服务隔离。如果此延迟加载模块之外的应用程序中的任何其他组件尝试引用服务,则会生成“超出注入器范围”错误
有关“附加模块”的更多信息,请参见本节:

此处的示例代码:


此处讨论循环依赖性问题:

确保在测试中导入模块,如下所示:

beforeEach(() => TestBed.configureTestingModule({
  imports: [DashboardModule]
}));

providedIn
不会自动注入服务,如果要遵循该特定路径,则需要使用
Injector
检索服务实例。@briosheje,你是说这个吗?如果没有,你能提供一个例子吗?不,对不起,我没有正确解释:如果你不使用“根”中提供的
,服务将不会是单例的。在您的情况下,您可以使用
providedIn:'root'
,或者以更简单的方式,将
仪表板服务
添加到
仪表板组件
提供程序中。@briosheje它将是每个仪表板模块实例的单例,我想这是他想要的。因此,如何使树在非根级别上可抖动才是真正的问题,因为
@Injectable
规范允许除
'root'
@SIARHEIPAKHUTA之外的其他值,这感觉像是一个角度错误。您的工作方式与前面描述的完全相同,
在下面的摘录中明确指出,@Injectable decorator用于配置一个提供程序,该提供程序将在包含HeroModule的任何注入器中可用。
实际上,您显示的链接是提供服务的两种方式。第一种方法是你因为一个奇怪的原因而失败。所以是的,添加到提供者是有效的,但是你失去了树的能力shaking@PierreDuc“奇怪的理由”是什么意思?您能否提供一个示例,说明如何使用不在根(应用程序)级别的服务并保持树抖动的能力?顺便说一句,我已经看过你的原始问题帖子了。所以,你认为这是一个角虫。也许吧,但我不敢相信Google团队失败了),因为他们使用了
providedIn:DashboardModule
而没有将其添加到模块的providers数组中。但不知何故,这就是愚蠢。你运行的是最新版本吗,因为这真的感觉像是一个bugI使用版本6.0.4的AngularIn演示代码使用的是6.0.7,这是最新版本谢谢!我不知道“lazymodule”选项。我看到其他人使用了一种“变通方法”,即创建一个名为ServiceModule的空模块,以避免循环依赖。似乎无法达到目的,因为在LazyModule级别使用providers[]会产生相同的结果,但不会产生相同的结果。使用提供程序数组不支持树抖动。因此,任何未使用的代码都不会被删除。也许这不是你特定项目的问题?啊,好吧,我想我明白我错在哪里了。我对树摇晃有一个更广泛的定义,包括懒惰的装载。我的困惑可能来自这样一个事实:providedIn不仅给我们带来了树震动(删除死代码),而且还允许我们延迟加载(应用程序范围的)单例服务,因为providers数组迫使我们将应用程序范围的单例下载到main.js包中。在我看来,如果你是在一个懒惰的模块中提供服务,那么你肯定是usi
beforeEach(() => TestBed.configureTestingModule({
  imports: [DashboardModule]
}));