【问题标题】:Angular 2 multi-provider for exporting depencency's dependencies用于导出依赖项的 Angular 2 多提供程序
【发布时间】:2016-03-03 17:35:37
【问题描述】:

我即将使用multi-provider 来导出我的依赖项及其自身的依赖项,以便它们可以立即注入到组件中。

对于一个组件

import {Component} from 'angular2/core';
import { FOO_PROVIDERS } from './foo';

@Component({
  selector: 'app',
  providers: [FOO_PROVIDERS]
})
export class App {}

following

import {Inject, Injectable, provide} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

export class Foo {
  constructor(@Inject(Http) http) {}
}

export const FOO_PROVIDERS = [
  provide(Foo, { useClass: Foo, multi: true }),
  provide(Foo, { useValue: HTTP_PROVIDERS, multi: true })
];

会导致

没有 Http 提供者! (App -> Foo -> Http)

还有this

import {Inject, provide} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

class Foo {
  constructor(@Inject(Http) http) {}
}

export const FOO_PROVIDERS = [Foo, HTTP_PROVIDERS];

会正常工作,而我希望他们能做类似的工作。

在这种情况下是否可以正确使用多提供者?

【问题讨论】:

  • 作为一个注释:我有一个挂断 - 确保在定义类 FOO 之后放置 FOO_PROVIDERS,而不是之前
  • @Tucker 没错,类没有提升。

标签: javascript typescript angular angular2-services


【解决方案1】:

当您注册provide(Foo, ...), 时,您就可以

constructor(foo:Foo)

使用multi: true,您将通过所有注册为Foo 的提供者

constructor(foo:any)

export const FOO_PROVIDERS = [
  provide(Foo, { useClass: Foo, multi: true }),
  provide(Foo, { useValue: HTTP_PROVIDERS, multi: true })
];

constructor(@Inject(Foo) foo:Foo[])

您将被传递给foo 一个包含Foo 实例的数组和作为第二项的提供者列表(这些包含在HTTP_PROVIDERS 中)

更新

也许你对应该发生的事情有不同的期望。我看不出@Inject(Http) http 与这里有什么关系。 HTTP_PROVIDERS 仅注册为 Foo 的值。解析提供程序时,您传递给useValue 的值无关紧要。 DI 为Foo 查找提供程序并传递分配的值,并且根本不关心该值是什么。在您的示例中没有Http 的提供者,因此Foo 本身无法注入Http。您需要注册Http,这在您将HTTP_PROVIDERS 直接添加到提供程序时完成(不在useValue 中),因为HTTP_PROVIDERS 包含Http(相当于provide(Http, {useClass: Http})

更新2

// An injected service that itself needs to get passed in a dependency
@Injectable()
class Foo {
  constructor(private http:Http);
}

// container for a bunch of dependencies    
@Injectable()
class MyProviders {
  // add everything you want to make available in your components
  constructor(public foo:Foo, public bar:Bar, ...);
}

class MyComponent {
  // inject just MyProviders and use the dependencies it provides
  constructor(private providers: MyProviders) {
    // access provided values
    providers.foo.doSomething();
    providers.bar.doSomethingElse();
  }
}

// Add all providers to allow DI to resolve all above dependencies
bootstrap(AppComponent, [HTTP_PROVIDERS, Foo, Bar]);

}

【讨论】:

  • 很遗憾,我无法验证这一点。 Thisthis 会导致注入Foo 实例(与constructor(@Inject(Foo) foo)),唯一的区别是在多提供者的情况下无法解析Http。并且做constructor(foo:Foo[]) 会抛出'No provider for Array! (应用程序 -> 数组)'。
  • 如果您将 FOO_PROVIDERS 添加到 Apps 提供程序而不是 Foo plnkr.co/edit/mxet3Knfirnsf2jA0XGu?p=preview,这在您的第一个 Plunker 中运行良好
  • 其实不是,注意that @Inject(Http) http被故意注释以确保注入的foo不是数组而是Foo实例。对于未注释的依赖项(问题中的first example),问题与描述的相同。所以目前还不清楚这里使用多提供者有什么问题,以及答案如何适用于这种情况。
  • 我更新了我的答案。评论太长了。随时提出后续问题。
  • 好的,谢谢,所以我做的事情似乎是不可能的,因为多提供者不会将 Http 暴露为单独的可注入对象,而是将其作为 Foo 提供者的一部分(不知道如何然后通过Foo 访问它),不是吗?您能否添加一个 plunker 来演示答案的第一部分?我无法复制它。
猜你喜欢
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2013-06-12
  • 2016-11-14
  • 2018-08-21
  • 2016-04-23
相关资源
最近更新 更多