我有以下课程ModuleWithHttp
:
@Injectable()
export default class {
constructor(private fetchApi: FetchApi) {}
}
我想按如下方式使用它:
@Component({
selector: 'main',
providers: [FetchApi]
})
export default class extends ModuleWithHttp {
onInit() {
this.fetchApi.call();
}
}
所以通过扩展已经注入依赖项的超类,我希望能够在其子代中访问它。
我尝试了许多不同的方法,甚至将超类作为组件:
@Component({
providers: [FetchApi]
})
export default class {
constructor(private fetchApi: FetchApi) {}
}
但是,this.fetchApi
仍然是null
,即使是在超级班级。
答案 0 :(得分:65)
如果你想避免这种“锅炉板”代码在子类中注入服务只是为了在父类的构造函数中注入,然后通过继承在子类中有效地使用这些服务,你可以这样做:
编辑:来自Angular 5.0.0 ReflectiveInjector已被弃用,转而使用StaticInjector,下面是更新代码以反映此更改
拥有deps的服务地图,
export const services: {[key: string]: {provide: any, deps: any[], useClass?: any}} = {
'FetchApi': {
provide: FetchApi,
deps: []
}
}
有一个注射器支架,
import {Injector} from "@angular/core";
export class ServiceLocator {
static injector: Injector;
}
在AppModule中设置,
@NgModule(...)
export class AppModule {
constructor() {
ServiceLocator.injector = Injector.create(
Object.keys(services).map(key => ({
provide: services[key].provide,
useClass: services[key].provide,
deps: services[key].deps
}))
);
}
}
在父类中使用注入器
export class ParentClass {
protected fetchApi: FetchApi;
constructor() {
this.fetchApi = ServiceLocator.injector.get(FetchApi);
....
}
}
并扩展父类,因此您无需注入FetchApi
服务。
export class ChildClass extends ParentClass {
constructor() {
super();
...
}
onInit() {
this.fetchApi.call();
}
}
答案 1 :(得分:35)
您必须在超类中注入fetchAPI并将其传递给子类
export default class extends ModuleWithHttp {
constructor(fetchApi: FetchApi) {
super(fetchApi);
}
onInit() {
this.fetchApi.call();
}
}
这是DI一般工作方式的一个特点。超类将通过继承实例化子进程,但您必须向子进程提供所需的参数。
答案 2 :(得分:19)
可能是迟到的响应,但我已经解决了只在BaseComponent和所有子类中注入注入器的问题,这样我就不需要维护服务定位器了。
我的基类:
constructor(private injectorObj: Injector) {
this.store = <Store<AppState>>this.injectorObj.get(Store);
this.apiService = this.injectorObj.get(JsonApiService);
this.dialogService = this.injectorObj.get(DialogService);
this.viewContainerRef = this.injectorObj.get(ViewContainerRef);
this.router = this.injectorObj.get(Router);
this.translate = this.injectorObj.get(TranslateService);
this.globalConstantsService = this.injectorObj.get(GlobalConstantsService);
this.dialog = this.injectorObj.get(MatDialog);
this.activatedRoute = this.injectorObj.get(ActivatedRoute);
}
我的孩子班:
constructor( private injector: Injector) {
super(injector);
}
答案 3 :(得分:0)
app.run(host='0.0.0.0')
请注意,尽管MyService1和MyService2是MyBaseClass创建的新实例