在angular2中,可以在@Component元素中定义提供者,如
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
providers : [ DataService ]
})
export class HomeComponent implements OnInit {
...
}
以及
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [ DataService ],
bootstrap: [AppComponent ]
})
export class AppModule { }
在@NgModule或@Component中定义提供程序有什么区别?如果我应该选择两个中的一个,那么定义提供者的更好的地方是什么?
答案 0 :(得分:5)
<强> @NgModule:强> service将是注入服务的模块的子组件内的单例(在构造函数内)。
@Component:服务将是组件及其子组件内的单例。
何时使用NgModule以及应用程序组件?
一方面,NgModule中的提供程序在根注入器中注册。这意味着在整个应用程序中可以访问在NgModule中注册的每个提供者。
另一方面,在应用程序组件中注册的提供程序仅在该组件及其所有子组件上可用。
答案 1 :(得分:5)
Angular应用程序是一个组件树。每个组件都有自己的注入器。因此,你有一个注射器树。假设您有以下设置:
AppComponent
/ \
C1 C2
/ \
C3 C4
现在,如果您在任何@NgModule
内定义了一个提供程序(除了延迟加载的那个),您就可以在任何组件中访问该提供程序(C1, C2, C3, C4
) 。如果您在@Component
中定义提供商,例如C2
,则只有C2
及其子C2
才能访问该提供商。但即使这是可配置的。您可以使用其他装饰器(如@Self
)来搜索组件声明的依赖项。
答案 2 :(得分:3)
区别在于范围。
实际上
providers: [...]
是“提供”将导致多个实例
如果提供程序在组件中注册,则可能会获得与提供组件实例一样多的提供程序值(服务实例)实例。 “可能”因为如果有提供者,但实际上从未注入过,那么就不会创建任何实例。
查找提供商
当DI创建组件,指令,管道或服务实例时,它会检查当前注入器的提供者构造函数参数。 如果进样器没有提供者,它会检查父进样器,直到它找到提供者或没有父进样器。
注射器hieararchy
在(非延迟加载)模块中注册的提供程序将添加到根注入器。延迟加载模块的注入器是子注入器。
AppComponent
s注入器也是根注入器的子注入器。
每个子组件或指令都会获取父组件注入器的子注入器。
将提供程序添加到组件或指令
这意味着,当您在组件上提供服务时,此组件及其后代组件将从向此组件注册的提供程序中获取实例。其他任何地方都找不到提供商,因此实例创建将失败。
如果此组件有多个实例,则每个组件(带有它的后代)将获得此服务的不同实例。
将提供商添加到模块
如果提供者在@NgModule()
(非延迟加载)中注册,则每个组件和服务都会找到此提供者,并且将在任何地方注入相同的实例。
向延迟加载的模块添加提供程序
如果提供者在延迟加载模块的@NgModule()
中注册,则该服务仅适用于此模块加载的组件和服务。