Angular 2使用现有提供者

Est*_*ask 15 javascript typescript angular2-services angular

useExisting提供者的用途是什么?

难道useExistingOrThrowIfThereIsNone还是useExistingOrCreateIfThereIsNone?根据我们的需要,可以某种方式有目的地选择其中一种行为吗?如果其中一个不受支持,是否可以模拟不受支持的一个?

文档完全不清楚,只是给出了一个useExisting可以重用实例的例子useClass.

Gün*_*uer 28

有了这个例子

providers: [
    A, 
    {provide: B, useClass: A}, 
    {provide: C, useExisting: A}]
Run Code Online (Sandbox Code Playgroud)

如果你有

constructor(private a: A)
Run Code Online (Sandbox Code Playgroud)

创建第一个提供程序的实例.

constructor(private b: B)
Run Code Online (Sandbox Code Playgroud)

创建第二个提供程序的实例

constructor(private c: C)
Run Code Online (Sandbox Code Playgroud)

注入第一个提供者的实例.

如果你重新开始

constructor(private c: C)
Run Code Online (Sandbox Code Playgroud)

创建并注入第一个提供程序的实例


ktr*_*yak 9

在编写时{provide: A, useClass: B},Angular将在标记 A 之间创建映射B

在编写时{provide: A, useExisting: B},Angular将在令牌 A令牌 之间创建映射B

这些地图之间的区别:

  • 令牌A->类B的实例
  • 令牌A->令牌B->令牌B的某个类的实例


Ale*_*nov 8

@GünterZöchbauer的答案仅作一点补充/说明。

当我们谈论令牌时,它实际上是使用ExistingOrThrowIfThereIsNone 。useExisting创建另一个令牌的别名,而不是instance,因此必须有useExisting引用的令牌,否则将引发异常。但是,当我们谈论实例时,只要链中的最后一个令牌注册实例,它就会起作用,因此从某种意义上讲,它是useExistingOrCreateIfThereIsNone。

考虑一下:

// T = token, I = instance
providers: [
    {provide: B, useClass: A}, // T[B] => I[A]
    {provide: C, useExisting: A}] // T[C] => ??? - there's no T[A] declared

...
constructor(private a: B) {} // works
...
constructor(private a: C) {} // throws an exception: 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,第二个声明将引发错误,因为令牌 C引用令牌 A,但是即使在注入器中有类A 的实例,也没有在任何地方声明令牌 A。Angular不会尝试为令牌 C 创建实例 A 或将令牌 C与现有实例 A 关联。我只是在我的一个项目中无意中对其进行了验证。:)

但是,由于其他答案中已充分描述的原因,以下内容将起作用:

providers: [
    {provide: B, useClass: A}, // T[B] => I[A]
    {provide: C, useExisting: B}] // T[C] => T[B] => I[A]

...

constructor(private a: B) {} // works
...
constructor(private a: C) {} // works
Run Code Online (Sandbox Code Playgroud)

在这个例子中的实例 A的将为创建令牌即使有没有C 实例以前创建的令牌 B.因此,对于令牌 C时是“用什么情况下应规定令牌 B”,并为令牌 B检查是“使用现有实例 A或如果不存在则创建新实例 ”。