角度文件说,在模块级别声明的提供程序对整个应用程序都是可见的:
引导模块的@NgModule.providers中列出的提供程序具有应用范围。向@NgModule.providers添加服务提供者可以有效地将服务发布到整个应用程序。
因此,这意味着可以将来自模块(AAAModule
)的服务注入另一个模块(BBBModule
)。但是,其他角度文件说我们可以通过在@NgModule
上声明提供程序来将提供程序的范围限制在特定的模块上。
可以使用providedIn元数据选项在模块级别为非根NgModule配置提供程序,以便将提供程序的范围限制在该模块上。
同样,另一份文件说我们可以将提供者的范围限制在特定的组件上:
NgModule中的各个组件都有自己的注射器。可以通过使用@Component元数据在组件级别配置提供程序,将提供程序的范围限制为组件及其子提供程序。
那么,事实是什么?如果我在模块级别声明了一个提供程序,那么它对整个应用程序还是模块都是可见的呢?“范围”是指提供者的“生命”吗?
发布于 2019-02-03 18:24:00
我认为在你的理解中,造成你困惑的缺失部分是角的延迟加载特性。延迟加载的模块将有自己的注入器(但继承自根注入器)。因此,延迟加载的模块中列出的提供程序将被限定为该模块的作用域,并且只能在映射到该模块的路由中存活。
当模块导入到其他模块(不是延迟加载)时,那么这些模块中列出的所有提供程序都会合并到同一个注入器中。这些提供程序将在整个应用程序生命期内存活。
组件中列出的提供程序只能使用该组件的时间。例如,考虑一个列出提供程序并位于可以切换的*ngIf
中的组件。当组件被创建时,也就是创建提供者的时候。当组件被破坏时,提供者也是如此。提供程序只能在该组件和任何组件/指令中访问,它们所列出的提供程序是DOM树中的后代。
考虑以下例子:
- Providers listed in Module A reside in the root injector. That means that the provider is available across the whole app and lives for the entire life of the app.
- A child injector is created. Providers listed in Module B or the providers that are listed in any module that is imported into Module B will reside in that new injector.
到目前为止,我只讨论了模块文件中列出的提供程序。接下来是使用装潢工的最新惯例(从角度6开始)。我建议您看看这篇文章。虽然本文讨论了在模块中列出提供者的旧方法与使用providedIn
的新方法,但我认为它也可以帮助您理解提供程序可用的范围。
发布于 2019-02-03 18:32:00
引导模块的@NgModule.providers中列出的提供程序具有应用范围。向@NgModule.providers添加服务提供者可以有效地将服务发布到整个应用程序。
如果您在根模块装饰器providers
数组中声明提供程序,那么是的,范围是整个应用程序。它与根注入器相关联,使同一单例实例在整个application.If中可用,一个提供程序在一个功能模块中声明,那么除非导入该模块,否则它将不可用。但是,如果在根模块中声明,那么它在任何地方都是可用的。
可以使用providedIn元数据选项在模块级别为非根NgModule配置提供程序,以便将提供程序的范围限制在该模块上。
如果您使用@Injectable
并在providedIn
属性中提到提供者的作用域,那么只有那些正在导入声明服务的模块的模块才会得到该实例。这就启用了树抖动,这实际上意味着如果在应用程序中不使用提供程序代码,则将其从最后的包中排除出来。
对于延迟加载的模块,创建根注入器的另一个子模块,它从根注入器中复制每件东西,再加上在惰性模块中声明的提供程序。在惰性加载组件的上下文中,提供者是从这个子注入器而不是从根注入器注入的。
NgModule中的各个组件都有自己的注射器。可以通过使用@Component元数据在组件级别配置提供程序,将提供程序的范围限制为组件及其子提供程序。
在这种情况下,每个组件都将获得它们自己的提供程序副本,它将是一个与根注入器中配置的实例不同的实例。当您需要一个您不希望跨组件共享的提供程序的私有副本时,请执行此操作。
https://stackoverflow.com/questions/54509360
复制相似问题