简体   繁体   English

Angular2 - 注入@Injectable

[英]Angular2 - inject into @Injectable

I have an Angular2 app with a service that is used for getting a data from an API. 我有一个Angular2应用程序,其中包含用于从API获取数据的service Following this example, I want to create a separate file which should contain some configuration data. 这个例子之后,我想创建一个单独的文件,其中应该包含一些配置数据。 My problem is that my service has an @Injectable() decorator and I'm not sure if I can pass it a provide array in the metadata in which I will inject the configuration as shown in the tutorial. 我的问题是我的服务有一个@Injectable()装饰器,我不确定我是否可以在元数据中传递一个provide数组,我将在其中注入配置,如教程中所示。 Anybody ever faced such a problem is welcome to share his solution :) 有人遇到过这样的问题,欢迎分享他的解决方案:)

In fact, Angular2 leverages hierarchical injectors and injectors are linked to components. 实际上,Angular2利用分层喷射器和喷射器链接到组件。 In short you can define providers only on components ( providers property) or at application level ( bootstrap function). 简而言之,您只能在组件( providers属性)或应用程序级别( bootstrap功能)上定义提供程序。

Regarding services, they will be able to use providers that are visible for the component that initiated the call but you can't define providers at their levels. 关于服务,他们将能够使用对发起呼叫的组件可见的提供者,但是您无法在其级别定义提供者。

Here is a sample: 这是一个示例:

Application
     |
AppComponent
     |
ChildComponent
  getData()     --- Service1 --- Service2

In such application, we have three injectors: 在这种应用中,我们有三个注射器:

  • The application injector that can be configured using the second parameter of the bootstrap function 可以使用bootstrap函数的第二个参数配置的应用程序注入器
  • The AppComponent injector that can be configured using the providers attribute of this component. 可以使用此组件的providers属性配置的AppComponent注入器。 It can "see" elements defined in the application injector. 它可以“看到”应用程序注入器中定义的元素。 This means if a provider isn't found in this provider, it will be automatically look for into this parent injector. 这意味着如果在此提供程序中找不到提供程序,它将自动查找此父注入程序。 If not found in the latter, a "provider not found" error will be thrown. 如果在后者中找不到,则会抛出“找不到提供者”错误。
  • The ChildComponent injector that will follow the same rules than the AppComponent one. ChildComponent注入器将遵循与AppComponent相同的规则。 To inject elements involved in the injection chain executed forr the component, providers will be looked for first in this injector, then in the AppComponent one and finally in the application one. 要注入为组件执行的注入链中涉及的元素,将首先在此注入器中查找提供者,然后在AppComponent者,最后在应用程序中AppComponent

This means that when trying to inject the Service1 into the ChildComponent constructor, Angular2 will look into the ChildComponent injector, then into the AppComponent one and finally into the application one. 这意味着,试图将注入时, Service1ChildComponent构造,Angular2将调查ChildComponent注射器,然后进入AppComponent一个最后进入应用程序之一。

Since Service2 needs to be injected into Service1 , the same resolution processing will be done: ChildComponent injector, AppComponent one and application one. 由于Service2需要被注入到Service1 ,相同分辨率的处理会做到: ChildComponent注射器, AppComponent一个应用程序之一。

This means that both Service1 and Service2 can be specified at each level according to your needs using the providers attribute for components and the second parameter of the bootstrap function for the application injector. 这意味着可以使用组件的providers属性和应用程序注入器的bootstrap函数的第二个参数,根据您的需要在每个级别指定Service1Service2

This answer could help you: 这个答案可以帮助你:

It is a bit strange, but only components can configure dependency injection in Angular (well, and bootstrap() , but that is essentially the same as the root component). 这有点奇怪,但只有组件可以在Angular(well和bootstrap()配置依赖注入,但这与root组件基本相同)。 Ie, only components can specify providers. 即,只有组件可以指定提供者。

As @Thierry mentions in his answer, each component in the component tree will get an associated "injector" if the component has a providers array specified. 正如@Thierry在他的回答中提到的,如果组件具有指定的providers数组,则组件树中的每个组件将获得关联的“注入器”。 We can think of this like an injector tree, that is (normally much) sparser than the component tree. 我们可以把它想象成一个注入器树,它(通常很多)比组件树更稀疏。 When a dependency needs to be resolved, this injector tree is consulted. 当需要解析依赖关系时,将查询此注入器树。 The first injector that can satisfy the dependency does so. 能够满足依赖性的第一个注入器就是这样做的。 The injector tree is walked up, toward the root component/injector. 注入器树朝向根组件/注入器向上走。

So, in order for your service to inject a configuration object dependency, that config object first has to be registered with an injector. 因此,为了使您的服务注入配置对象依赖项,首先必须使用注入器注册该配置对象。 Ie, in a component's providers array, call 即,在组件的providers数组中,调用
provide(stringToken or OpaqueToken, {useValue: MyConfigObject} )
This registration must occur somewhere at or above the component where you want to use/inject your service. 此注册必须发生在您要使用/注入服务的组件或其上方某处。

Your service should then be able to @Inject the registered config object, because it will find it in the injector tree. 然后,您的服务应该能够@Inject注册的配置对象,因为它将在注入器树中找到它。

Note, since only components can configure providers, the @Injectable() decorator does not support any configuration options, so a providers array is not supported. 请注意,由于只有组件可以配置提供程序,因此@Injectable()装饰器不支持任何配置选项,因此不支持providers数组。

This is not supported. 这不受支持。 For services the providers need to be added to bootstrap(AppComponent, [..., Service, ServiceDependency1, ...]) 对于服务,需要将提供程序添加到bootstrap(AppComponent, [..., Service, ServiceDependency1, ...])

See also https://github.com/angular/angular/issues/5622 另见https://github.com/angular/angular/issues/5622

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

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