简体   繁体   English

注入@Component中的提供程序和@Module之间的Angular2有什么区别?

[英]What is the difference in Angular2 between inject a provider in @Component and @Module?

In angular2 it is possible to define the providers in a @Component element like 在angular2中,可以在@Component元素中定义提供者

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
  providers : [ DataService ]
})
export class HomeComponent implements OnInit {

...
}

and also in a 还有一个

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [ DataService ],
  bootstrap: [AppComponent ]
})
export class AppModule { }

what is the difference between define the provider in the @NgModule or in a @Component? 在@NgModule或@Component中定义提供程序有什么区别? and If I should choose one of two, what should be the better place to define the provider ? 如果我应该选择两个中的一个,那么定义提供者的更好的地方是什么?

@NgModule: service will be a singleton inside the child components of that module that injects the service (inside the constructor). @NgModule: service将是注入服务的模块子组件内的单例(在构造函数内)。

@Component: service will be a singleton inside the component and its child components. @Component: service将是组件内部的单例及其子组件。

Source: https://angular.io/docs/ts/latest/guide/dependency-injection.html#when-to-use-the-ngmodule-and-when-an-application-component- 资料来源: https//angular.io/docs/ts/latest/guide/dependency-injection.html#when-to-use-the-ngmodule-and-when-an-application-component-

When to use the NgModule and when an application component? 何时使用NgModule和应用程序组件?

On the one hand, a provider in an NgModule is registered in the root injector. 一方面,NgModule中的提供程序在根注入器中注册。 That means that every provider registered within an NgModule will be accessible in the entire application. 这意味着在整个应用程序中可以访问在NgModule中注册的每个提供者。

On the other hand, a provider registered in an application component is available only on that component and all its children. 另一方面,在应用程序组件中注册的提供程序仅在该组件及其所有子组件上可用。

Angular application is a tree of components. 角度应用程序是一个组件树。 Each component has its own injector. 每个组件都有自己的注入器。 Hence, you have a tree of injectors. 因此,你有一个注射器树。 Suppose, you have the following setup: 假设您有以下设置:

    AppComponent
  /            \
 C1            C2
              /  \
            C3   C4

Now, if you define a provider inside any @NgModule (except the one this is lazy loaded), you'll be able to access that provider in any of the components ( C1, C2, C3, C4 ). 现在,如果您在任何@NgModule定义了一个提供程序(除了延迟加载的那个),您将能够在任何组件( C1, C2, C3, C4 )中访问该提供程序。 If you define a provider in @Component , say in C2 , only C2 and its children C2 will be able to access that provider. 如果在@Component定义提供程序,例如在C2 ,则只有C2及其子C2才能访问该提供程序。 But even this is configurable. 但即使这是可配置的。 You can use additional decorators like @Self to search for a dependency declared by the component. 您可以使用其他装饰器(如@Self来搜索组件声明的依赖项。

The difference is the scope. 不同之处在于范围。

Actually 其实

  • "injecting" is adding a parameter to a constructor. “injecting”是将一个参数添加到构造函数中。
  • Adding it to providers: [...] is "providing" 将其添加到providers: [...]是“提供”

providing at a component will result in multiple instances 提供组件将导致多个实例

If a provider is registered in a component, you get potentially as many instances of the providers value (service instance) as there are component instances. 如果提供程序在组件中注册,则可能会获得与组件实例一样多的提供程序值(服务实例)实例。 "potentially" because if there is a provider, but it is never actually injected, then no instance will be created. “可能”因为如果有提供者,但实际上从未注入过,那么就不会创建任何实例。

looking up providers 寻找提供者

When DI creates a component, directive, pipe, or service instance, it checks the current injector for providers the constructors parameters. 当DI创建组件,指令,管道或服务实例时,它会检查当前注入器的提供者构造函数参数。 If the injector doesn't have a provider, it checks parent injectors until it finds a provider or there are no parent injectors. 如果进样器没有提供者,它会检查父进样器,直到找到提供者或没有父进样器。

injector hieararchy Providers registered in (non-lazy loaded) modules are added to the root injector. 注入器hieararchy注册在(非延迟加载)模块中的提供者被添加到根注入器。 Lazy loaded module's injector is a child injector. 延迟加载模块的注入器是子注入器。 The AppComponent s injector is also a child injector of the root injector. AppComponent的注入器也是根注入器的子注入器。 Every child component or directive gets a child injector of the parent components injector. 每个子组件或指令都获取父组件注入器的子注入器。

adding a provider to a component or directive 将提供程序添加到组件或指令

This means, when you provide a service on a component, this component and its descendant components get an instance from the provider registered with this component. 这意味着,当您在组件上提供服务时,此组件及其后代组件将从向此组件注册的提供程序中获取实例。 Everywhere else no provider will be found and therefore instance creation will fail. 在其他任何地方都找不到提供者,因此实例创建将失败。

If there are multiple instances of this component, then each component (with it's descendants) will get a different instance of this service. 如果此组件有多个实例,则每个组件(带有它的后代)将获得此服务的不同实例。

adding a provider to a module 向模块添加提供程序

If a provider is registered in @NgModule() (non-lazy loaded) every component and service will find this provider, and the same instance will be injected everywhere. 如果提供程序在@NgModule()注册(非延迟加载),则每个组件和服务都将找到此提供程序,并且将在任何位置注入相同的实例。

adding a provider to a lazy-loaded module 将提供程序添加到延迟加载的模块

If a provider is registered in @NgModule() of a lazy loaded module, then the service will only be available for components and services loaded by this module. 如果提供程序在延迟加载的模块的@NgModule()中注册,则该服务仅可用于此模块加载的组件和服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM