Joh*_*ohn 18 dependency-injection typescript angular
假设我有一个Angular 2组件指令,我希望组件使用的注入依赖项由@Input()确定.
我想写类似的东西<trendy-directive use="'serviceA'">并让TrendyDirective的实例使用serviceA,或者让它使用serviceB,如果这是我指定的.(这是我实际尝试做的过于简单的版本)
(如果你认为这是一个可怕的想法,我会对这些反馈持开放态度,但请解释原因.)
这是如何实现我的想法的一个例子.在这个例子中,假设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();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这在技术上可行,但必须有更好的方法来进行动态依赖注入.
Est*_*ask 10
它是
// can be a service also for overriding and testing
export const trendyServiceMap = {
serviceA: ServiceA,
serviceB: ServiceB
}
constructor(private injector: Injector) {}
...
ngOnInit() {
if (trendyServiceMap.hasOwnProperty(this.use)) {
this.service = this.injector.get<any>(trendyServiceMap[this.use]);
} else {
throw new Error(`There's no such thing as '${this.use}'`);
}
}
Run Code Online (Sandbox Code Playgroud)
通常,Angular2文档中介绍了相同的方法:InjectorComponent
@Component({
providers: [Car, Engine, Tires, heroServiceProvider, Logger]
})
export class InjectorComponent {
car: Car = this.injector.get(Car);
heroService: HeroService = this.injector.get(HeroService);
hero: Hero = this.heroService.getHeroes()[0];
constructor(private injector: Injector) { }
}
Run Code Online (Sandbox Code Playgroud)
您必须注入Injector构造函数并在注释providers属性中列出所有服务@Component。然后,您可以injector.get(type)在哪里type解决您的问题@Input。根据文档,Service直到您要求时(.get())才真正注入。