2016-12-05 5 views
2

私が作成しやすいモデルに関連したサービスを行うために、一般的なAPIサービスを作成したい:継承依存性の注入

@Injectabe() 
export class FooService extends ModelService<Foo>{ 

} 

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を管理し、私のサービスを作成します。

しかし、fooService.getAll().subscribe(...);を呼び出すと、apiServiceが定義されていないというエラーが表示されます(未定義のプロパティ 'get'を取得できません)。

ので、修正は次のようにFooServiceにコンストラクタを追加することです:

constructor(api: ApiService) { 
    super(api); 
} 

しかし、問題は、それがDEV-友好的ではないということです、何もそうするように説明しますないとFooServiceModelServiceを拡張するので、それが持っている必要があります同じコンストラクタなので、同じ依存関係になります。

依存関係を継承する方法はありますか?

PS:既に@Injectable()ModelServiceを追加しようとしましたが、同じエラーが発生しました。

EDIT: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", 
    ... 
    ... 
    } 

答えて

2

。子クラスには@Injectable()デコレータが必要です。

独自の依存関係を持ち、独自のコンストラクタが必要な子クラスの場合、依存関係は明示的にsuperに渡されます(他の回答を参照)。 JavaScriptでは、rest演算子と@Injectを使用していくつかの繰り返しをスキップすることができますが、TypeScriptではすべてのコンストラクタパラメータを明示的に列挙することが安全です。

+0

私は 'FooService'から' @Injectable() 'を削除しようとしましたが、それを' ModelService'に追加しました。したがって、コンストラクタを使用して依存関係を明示的に渡すことなく、正しく処理する方法はありませんか? – Supamiu

+0

これは意図したとおりに動作するはずです。 http://plnkr.co/edit/WwslqHcOUxKj4tQxIs23?p=preview複製できる問題がある場合は、[MCVE](http://stackoverflow.com/help/mcve)を提供してください。 – estus

+0

質問のコードにFooServiceのコンストラクタがありません。コンストラクタが必要な場合は、 '@ Injectable'または' @Inject'が必要です。 – estus

5

コンストラクタは、依存関係を繰り返す必要があり、その後super(...)

@Injectabe() 
export class FooService extends ModelService<Foo>{ 
    constructor(apiService: ApiService) { 
     super(apiService); 
     //ApiService is a service that wraps Http and adds signature , auth and serialization. 
    } 
} 

を使用してスーパークラスに渡される。これは、ではありませんAngular2要件またはliこれは、コンストラクタがTypeScriptでどのように動作するかを示しています。余分な依存関係を導入しないと、それは(それが型注釈ではなく@Injectを使用している場合)デコレータは、親クラスのために必要とされる

@Injectable() 
export abstract class ModelService<T> {...} 

export class FooService extends ModelService<Foo>{ 

} 

@Injectable()ある独自のconstructorを必要としない子クラスのために

+1

'apiService'が親コンストラクタで修飾子を持つ場合、二重代入を避けるために' constructor(apiService:ApiService){'のみでなければなりません。 – estus

+0

ありがとうございます@stus、あなたはもちろんそうです。私は少しばかげていた: -/ –

+0

はい私は質問で言ったように私は知っている。ここでの問題は、それを処理するためのより良い方法を見つけることです:/このケースを処理する予定はありませんか? – Supamiu