我有一个班级结构,需要一个BaseModel
和很多ChildModels
。像这样
// BaseModel type
import { Injectable } from '@angular/core';
@Injectable()
export class BaseModel {
constructor() {
}
public _instanceUrl(): string {
return '';
};
public url(): string {
return 'BASE_URL_' + this._instanceUrl();
};
}
// ChildModel type
import { BaseModel } from './base-model';
import { Injectable } from '@angular/core';
@Injectable()
export class ChildModel extends BaseModel {
constructor() {
super();
}
public _instanceUrl(): string {
return "CHILD_URL";
}
}
// BaseService type
import { Injectable} from '@angular/core';
import { BaseModel } from '../models/base-model';
@Injectable()
export class BaseService<T extends BaseModel> {
private url: string;
constructor(private childInstance: T) {
}
public getUrl() {
return this.childInstance.url();
}
}
这是我的AppModule实现:
@NgModule({
declarations: [
AppComponent
],
imports: [
HttpClientModule,
BrowserModule,
AppRoutingModule,
ServicesModule
],
providers: [BaseService],
bootstrap: [AppComponent]
})
export class AppModule { }
这是我使用该服务的地方
import { Component } from '@angular/core';
import { BaseService } from './modules/services/base-service/base-service.service';
import { ChildModel } from './modules/services/models/child-model';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
title = 'angular-test';
preventAbuse = false;
constructor(private baseService: BaseService<ChildModel>) {
}
testHttp() {
console.log(this.baseService.getUrl());
}
}
我需要知道 Angular 是否有可能为T
(在这种情况下为BaseService
)的构造函数中提供正确的类型ChildModel
。现在,我收到一条错误消息,说它不能提供构造函数参数。
未捕获的错误:无法解析BaseService的所有参数: (?)。
如果我从BaseService
的构造函数中删除了该参数,则该服务创建成功。问题不是注入BaseService
,而是注入T类型的BaseService
构造函数参数。而且,我可能有数百个子类,所以我想避免全部提供它们。不过,我不确定这是否可能。
我正在使用最新版本的Angular和Typescript
Angular CLI: 7.3.4
Angular: 7.2.7
typescript: 3.2.4
这里是Stackblitz
的链接答案 0 :(得分:0)
一个简单的解决方案是使用Injection of Generic Services in Angular
建议的工厂模式providers: [{
provide: 'baseService',
useFactory: (childModel: ChildModel) => (new BaseService<ChildModel>(childModel)),
deps: [ChildModel]
}]
constructor(@Inject('baseService') private baseService: BaseService<ChildModel>) {
console.log(baseService.getUrl()); // output "BASE_URL_CHILD_URL"
}