假设我有一个Angular 2 component-directive,我希望组件使用的注入依赖项由@Input()确定。
我想写一个类似<trendy-directive use="'serviceA'">
的东西,让TrendyDirective的示例使用serviceA,或者让它使用serviceB(如果我指定的话)。
(If你认为这是一个可怕的想法开始,我开放的反馈,但请解释为什么。
这里有一个例子来说明如何实现我所想的。在这个例子中,假设ServiceA和ServiceB都是可注入的,它们都通过一个“superCoolFunction”实现了iService。
@Component({
selector: 'trendy-directive',
...
})
export class TrendyDirective implements OnInit {
constructor(
private serviceA: ServiceA,
private serviceB: ServiceB){}
private service: iService;
@Input() use: string;
ngOnInit() {
switch (this.use){
case: 'serviceA': this.service = this.serviceA; break;
case: 'serviceB': this.service = this.serviceB; break;
default: throw "There's no such thing as a " + this.use + '!';
}
this.service.superCoolFunction();
}
}
我认为这在技术上是可行的,但必须有一个更好的方法来进行动态依赖注入。
6条答案
按热度按时间kx7yvsdv1#
是的
nuypyhwy2#
一般来说,Angular2文档中描述了相同的方法:注射器组件
您必须在构造函数中注入
Injector
,并在@Component
annotation的providers
属性中列出所有服务。然后您可以injector.get(type)
,其中type
将从@Input
解析。根据文档,Service
实际上不会注入,直到您要求它(.get()
)。njthzxwz3#
我想进一步介绍Estus Flask answer,创建一个导入服务的逻辑,而不必将名称声明为数组对象。
基本上,我们只需要传入服务的
path
和name
,其余的几乎相同。现在,您可以访问
dynamicService
中的函数,如下所示:(Let假设我们需要的服务中有一个http可观察的fn)
9cbw7uwe4#
在这里你有一个方法,有点复杂,但工作像一个魅力!
在一个共享模块和多个自定义实现中设置默认搜索服务。并且不必显式引用所有可能的实现。
接口和默认实现
使用InjectionToken创建服务实现列表
默认服务实现的提供程序
自定义实现(可以在另一个模块上)
为自定义实现添加令牌
添加提供程序
最后,在组件中
iq0todco5#
在@angular/core模块中有一个名为Inject的服务。使用@Inject可以实现替代的注入方式。但这只能在构造函数中完成。
所以你需要将组件的输入放入@component装饰器的inputs数组中(不要在类中使用@Input装饰器),然后将该输入变量注入构造函数中。
v440hwme6#
这可能为时已晚,但可能有一些有趣和整洁的解决方案动态注入的一些条件。主要思想是使用服务 Package 器和添加方法或getter来获取必要的服务的适当示例:
这两个服务都实现了抽象类UserCredentialsService,
instance
getter通过条件适当的示例获得。