Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular 2使用现有的提供者_Javascript_Typescript_Angular_Angular2 Services - Fatal编程技术网

Javascript Angular 2使用现有的提供者

Javascript Angular 2使用现有的提供者,javascript,typescript,angular,angular2-services,Javascript,Typescript,Angular,Angular2 Services,useExistingprovider的用法是什么 它是useExistingorRowwhere无还是useExistingorCreateWhere无?能否根据我们的需要,有目的地选择其中一种行为?如果其中一个不受支持,是否可以模拟不受支持的一个 文档对此完全不清楚,只是给出了一个示例,说明useExisting可以在这个示例中重用useClass中的实例 providers: [ A, {provide: B, useClass: A}, {provide: C

useExisting
provider的用法是什么

它是
useExistingorRowwhere无
还是
useExistingorCreateWhere无
?能否根据我们的需要,有目的地选择其中一种行为?如果其中一个不受支持,是否可以模拟不受支持的一个

文档对此完全不清楚,只是给出了一个示例,说明
useExisting
可以在这个示例中重用
useClass

中的实例

providers: [
    A, 
    {provide: B, useClass: A}, 
    {provide: C, useExisting: A}]
如果你有

constructor(private a: A)
将创建第一个提供程序的实例

constructor(private b: B)
将创建第二个提供程序的实例

constructor(private c: C)
注入第一个提供程序的实例

如果你从新开始

constructor(private c: C)

当我们编写
{provide:A,useClass:B}
时,将创建并注入第一个提供者的实例,Angular将在标记
A
B
之间创建映射


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

这些地图之间的区别:

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

只是对@GünterZöchbauer的答案作了一点补充/澄清

当我们谈论代币时,如果没有代币,那么它实际上会被使用。useExisting为另一个令牌创建别名,而不是实例,因此必须是useExisting引用的令牌,否则将引发异常。但是,当我们谈论实例时,只要链中的最后一个令牌注册实例,它就可以工作,因此从这个意义上说,如果没有实例,它就可以使用existingorcreate

考虑这一点:

// 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: 
在这种情况下,第二次声明将抛出一个错误,因为令牌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

在本例中,将为令牌C创建实例,即使之前没有为令牌B创建实例A。因此,对于令牌C,它是“使用应为令牌B提供的任何实例”,对于令牌B,它是“使用现有实例A,如果没有实例,则创建新实例”。

useExisting
就像另一个提供者的别名
useClass
只是一个从请求的类型映射到实际类型的新提供程序,但键是请求的类型。您不需要做任何事情就可以使
Service
在任何地方都成为单例,只需在根组件上提供一次即可。Angular2的DI为每个提供者维护一个实例。如果只提供一次,则只有一个实例。目前不支持此操作。另外,Angular2提供的
ROUTER\u PROVIDERS
等内容必须明确添加到
bootstrap()
或根组件。为了避免在两个不同的提供程序指向同一类时创建两个不同的实例。很好的示例,遇到了相同的问题场景,最后一行是错误的!对于令牌B,它是“创建a的新实例”(无论是否存在一个实例)Nope。最后一行是正确的。实例是可重用的,默认情况下由angular缓存。如果你的情况不是这样的话,那么还有别的事情要发生。在单独的问题中发布代码,有人会回答。