问题描述
我想创建一个通用的api服务,以使与模型相关的服务更易于创建:
I want to create a generic api service in order to make model-related services easier to create:
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);
}
}
然后,我将创建管理模型 Foo
的服务:
then, I will create my service that manages model Foo
:
@Injectabe()
export class FooService extends ModelService<Foo>{
}
但是当我调用 fooService.getAll().subscribe(...);
时,我收到一条错误消息,提示未定义 apiService
(无法获取属性'get'的).
But when I call fooService.getAll().subscribe(...);
I get an error saying that apiService
is undefined (cannot get property 'get' of undefined).
因此解决方法是在 FooService
中添加一个构造函数,如下所示:
So the fix is to add a constructor in FooService
like this:
constructor(api: ApiService) {
super(api);
}
但是问题在于它不是对开发人员友好的,什么也没有告诉您这样做,并且由于 FooService
扩展了 ModelService
,因此它应该具有相同的构造函数,因此具有相同的依赖关系
But problem is that it's not dev-friendly, nothing tells you to do so and since FooService
extends ModelService
, it should have the same constructor and therefore the same dependencies.
有什么方法可以继承依赖项吗?
Is there any way to inherit dependency?
PS:我已经尝试将 @Injectable()
添加到 ModelService
,同样的错误.
PS: I already tried to add @Injectable()
to ModelService
, same error.
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"
]
}
}
package.json
:
"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",
...
...
}
推荐答案
对于不引入额外依赖项并且不需要自己的构造函数
的子类,
For child class that doesn't introduce extra dependencies and doesn't need its own constructor
it is
@Injectable()
export abstract class ModelService<T> {...}
export class FooService extends ModelService<Foo>{
}
父类需要
@Injectable()
装饰器(如果它使用类型注释而不是 @Inject
).子类不需要 @Injectable()
装饰器.
@Injectable()
decorator is needed for parent class (if it uses type annotation and not @Inject
). No @Injectable()
decorator is needed for child class.
对于可能具有自己的依赖项并因此需要自己的构造函数的子类,应将依赖项显式传递给 super
(请参见其他答案).在JavaScript中,可以使用rest运算符和 @Inject
跳过某些重言式,但是对于TypeScript,可以安全地显式枚举所有构造函数参数.
For children classes that may have their own dependencies and thus need own constructors the dependencies should be explicitly passed to super
(see the other answer). In JavaScript, rest operator and @Inject
may be used to skip some tautology, but for TypeScript it is safe to enumerate all constructor parameters explicitly.
这篇关于继承依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!