angular - 有没有一种方法可以从多个级别使用 Angular 多提供程序?

标签 angular dependency-injection

我想知道是否有可能从(理想情况下)所有祖先那里获得 Angular 多供应商。

假设我有一个 INJECTION_TOKEN X 并且我有一个像这样的组件结构:

<comp-a>
    <comp-b>
       <comp-c></comp-c>
    <comp-b>
<comp-a>

comp-a 提供商: 提供者:{provide: X, useValue: "A", multi: true}

comp-b 提供商: 提供者:{provide: X, useValue: "B", multi: true}

当我使用依赖注入(inject)时,有没有办法在 comp-c 中获取 ["A", "B"]:

constructor(@Inject(X) obtainedArray:TypeOfX[]) {
    console.log(obtainedArray.length); //Expected to be 2
}

我曾尝试在 comp-b 中使用此提供程序,但它会引发循环 DI 预期:

providers:[
    {provide: X, useExisting: X, multi: true}
    {provide: X, useValue: "B", multi: true}
]

最佳答案

如以下文章所述:

Angular 通过使用原型(prototype)继承 在元素上存储提供者。因此,无论您是否使用 multi 都无所谓,您将获得以下对象,其中包含当前元素上的所有提供程序:

enter image description here

如您所见,所有提供者都在这里,但由于 Angular 只有 uses square brackets要从元素中获取提供者,您将只能获得最近的提供者。

要解决此问题,您可以使用使用工厂收集所有父提供者的附加 token :

import { Component, VERSION, InjectionToken, 
  Inject, SkipSelf, Optional } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <comp-a>
        <comp-b>
            <comp-c></comp-c>
        </comp-b>
    </comp-a>
  `
})
export class AppComponent { }

const X = new InjectionToken('X');

const XArray = new InjectionToken('XArray');

const XArrayProvider = {
  provide: XArray,
  useFactory: XFactory,
  deps: [X, [new SkipSelf(), new Optional(), XArray]]
};

export function XFactory(x: any, arr: any[]) {
  return arr ? [x, ...arr] : [x];
}

@Component({
  selector: 'comp-a',
  template: `<ng-content></ng-content>`,
  providers: [
    { provide: X, useValue: "A" },
    XArrayProvider
  ]
})
export class CompA { }


@Component({
  selector: 'comp-b',
  template: `<ng-content></ng-content>`,
  providers: [
    { provide: X, useValue: "B" },
    XArrayProvider
  ]
})
export class CompB { }


@Component({
  selector: 'comp-c',
  template: `{{ tokens }}`
})
export class CompC {
  constructor( @Inject(XArray) public tokens: any[]) { }
}

Ng-run Example

关于angular - 有没有一种方法可以从多个级别使用 Angular 多提供程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49406615/

相关文章:

c# - 使用 Activator.CreateInstance 时解析注入(inject)的实例

c# - 使用 spring.net 创建字符串对象

c# - PCL 中的 xamarin securestring 等价物

java - Guice:类或实例级绑定(bind)注释

angular - 某些 Protractor API 函数会导致错误

angular - Firestore如何从另一个集合文档id中获取集合值被引用

javascript - ControlValueAccessor(更改)事件被触发两次(Angular 4)

angular - 为什么我得到 "Cannot find name ' NgModule '"despite running "npm i @types/node --global”?

c# - 在运行时在 ASP.Net Core 中安装新的中间件

Node.js 在使用 --watch 构建 Angular 6 期间崩溃