Angular 继承依赖注入
我想创建一个通用api服务,以便更容易创建与模型相关的服务:Angular 继承依赖注入,angular,typescript,Angular,Typescript,我想创建一个通用api服务,以便更容易创建与模型相关的服务: export abstract class ModelService<T> { constructor(protected apiService: ApiService) { //ApiService is a service that wraps Http and adds signature , auth and serialization. } public getAll(
export abstract class ModelService<T> {
constructor(protected apiService: ApiService) {
//ApiService is a service that wraps Http and adds signature , auth and serialization.
}
public getAll(): Observable<T[]> {
return this.apiService.get<T[]>(this.modelClass, this.baseUrl);
}
}
但是当我调用fooService.getAll().subscribe(…)代码>我收到一个错误,说明apiService
未定义(无法获取未定义的属性“get”)
因此,修复方法是在FooService
中添加一个构造函数,如下所示:
constructor(api: ApiService) {
super(api);
}
但问题是,它对开发人员不友好,没有任何命令您这样做,而且由于FooService
扩展了ModelService
,它应该具有相同的构造函数,因此具有相同的依赖项
有没有办法继承依赖关系
PS:我已经尝试将@Injectable()
添加到ModelService
,同样的错误
编辑:tsconfig.json
:
{
"compilerOptions": {
"baseUrl": "",
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es6",
"dom"
],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}
"dependencies": {
"@angular/common": "2.2.1",
"@angular/compiler": "2.2.1",
"@angular/core": "2.2.1",
"@angular/forms": "2.2.1",
"@angular/http": "2.2.1",
"@angular/platform-browser": "2.2.1",
"@angular/platform-browser-dynamic": "2.2.1",
"@angular/router": "3.2.1",
...
...
},
"devDependencies": {
"@angular/compiler-cli": "2.2.1",
...
...
}
package.json
:
{
"compilerOptions": {
"baseUrl": "",
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es6",
"dom"
],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}
"dependencies": {
"@angular/common": "2.2.1",
"@angular/compiler": "2.2.1",
"@angular/core": "2.2.1",
"@angular/forms": "2.2.1",
"@angular/http": "2.2.1",
"@angular/platform-browser": "2.2.1",
"@angular/platform-browser-dynamic": "2.2.1",
"@angular/router": "3.2.1",
...
...
},
"devDependencies": {
"@angular/compiler-cli": "2.2.1",
...
...
}
构造函数需要重复依赖项,然后使用super(…)
@Injectabe()
导出类FooService扩展了ModelService{
构造函数(apiService:apiService){
超级(apiService);;
//ApiService是一种包装Http并添加签名、身份验证和序列化的服务。
}
}
这不是Angular2要求或限制,这是构造函数在TypeScript中的工作方式。对于不引入额外依赖项且不需要自己的构造函数的子类
@Injectable()
export abstract class ModelService<T> {...}
export class FooService extends ModelService<Foo>{
}
@Injectable()
导出抽象类ModelService{…}
导出类FooService扩展了ModelService{
}
父类需要@Injectable()
装饰器(如果它使用类型注释而不是@injecte
)。子类不需要@Injectable()
装饰器
对于可能有自己的依赖项并因此需要自己的构造函数的子类,依赖项应该显式地传递给super
(参见另一个答案)。在JavaScript中,rest运算符和@Inject
可以用来跳过某些重言式,但对于TypeScript,可以安全地显式枚举所有构造函数参数。如果apiService
在父构造函数中有修饰符,则它应该是构造函数(apiService:apiService){
以避免双重赋值。谢谢@estus,你当然是对的。我有点马虎:-/是的,我知道我在问题中说过。问题是找到更好的方法来处理它:/n没有计划处理这种情况?没有什么需要处理的。这是构造函数的工作方式。这里的问题不是构造函数,我认为是继承,因为FooService
应该与ModelService
具有相同的构造函数,因此它应该具有相同的依赖注入需求。真正的问题是,我的IDE(WebStorm)说“嘿,你必须实现ModelService
的抽象方法”,但没有“嘿,你必须将依赖项传递给父级”。这样,另一个开发人员就可以使用ModelService
创建一个服务,然后像“伙计,它不工作了”一样来找我。我试图删除@Injectable()
从我的FooService
添加到ModelService
,依赖项注入仍然存在相同的问题。因此,如果不使用构造函数显式传递依赖项,就无法正确处理依赖项?它应该按预期工作。如果您有可以复制的问题,请提供。问题中的代码不正确FooService中没有构造函数。如果你需要构造函数,那么当然,你需要@Injectable
或@injection
那里。这很奇怪,它在你的plunkr中工作,当我在我的AppModule中复制粘贴时,它没有。我用你的plunker测试了一些其他可能性,并在config.js中添加了我的@angular版本,它仍然工作(仅在plunkr中)。我编辑了问题以添加tsconfig.json和package.json。不确定是什么原因导致了这种情况。我建议尝试使用显式注释,即构造函数(@Inject(ApiService)protected ApiService:ApiService){
@Injectable
,在这种情况下,任何地方都不需要。