有没有办法从所有多个级别使用 Angular 多提供程序?

问题描述 投票:0回答:2

我想知道是否有可能从(理想情况下)所有祖先那里获得角度多提供者。

假设我有一个

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

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

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

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

当我使用依赖注入时,有没有办法在

["A", "B"]
中获取
comp-c
,例如:

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 dependency-injection
2个回答
13
投票

正如以下文章所述:

Angular 通过使用原型继承在元素上存储提供者。因此,无论您是否使用

multi
,您都会得到以下对象,其中包含当前元素上的所有提供程序:

正如您所看到的,所有提供者都在这里,但由于 Angular 只是 使用方括号 从元素中获取提供者,您将只能获得最近的提供者。

要解决此问题,您可以使用使用工厂的附加令牌来收集所有父提供程序:

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 运行示例


0
投票

不,据我所知,您无法通过依赖注入做您想做的事情。当您在组件中提供某些内容时,它会自动隐藏具有相同令牌的先前提供者。这就是它的工作方式。

为了实现你所需要的,我能想到的唯一解决方案是将提供者作为

inputs
传递。

我的意思是,

comp-a
声明了一个提供者。
comp-b
也这样做,但接受包含提供者或提供者数组的
input
。然后
comp-b
可以将自己的提供者添加到数组中并将其作为输入传递给
comp-c

我不明白你到底为什么想要这个,但是......

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.