web-dev-qa-db-ja.com

抽象クラスTypeScript(Angular2)への依存性注入

抽象クラス(コンストラクターなし)があり、別のクラスを挿入したい。

抽象クラス:

import { ErrorHandler } from '../../shared/services/errorHandler.service';
import { Inject } from '@angular/core';


export abstract class BaseApiComponent<T> {
    @Inject(ErrorHandler) errorHandler: ErrorHandler;

    this.errorHandler.test();
}

注入されたクラス:

import { Injectable } from '@angular/core';

@Injectable()
export class ErrorHandler  {
  constructor() { }


  public test() {
    console.log('Test');
  }

}

そして、私は次のエラーがあります

ORIGINAL EXCEPTION: TypeError: Cannot read property 'test' of undefined

どうすれば修正できますか?

15
Max K

Angular 2 RC5の時点で、DIはより単純になります。@Injectable()で飾り付けをする必要はありません。 。

export class ErrorHandler {
    test() {
        console.log('ErrorHandler.test()');
    }
}

export abstract class BaseApiComponent<T> {
    // use protected property parameter in abstract class
    // for accessibility from descendants.
    constructor(protected errorHandler: ErrorHandler) {}

    someMethod() {
        this.errorHandler.test();
    }
}

export class ApiComponentImpl<T> extends BaseApiComponent<T> {
    // use @Inject decorator
    constructor(@Inject(ErrorHandler) errorHandler: ErrorHandler) {
        super(errorHandler);
    }
}

app.module.ts

// class declarations
@NgModule({
    providers: [
        ErrorHandler,
        ApiComponentImpl
    ]
})
export class AppModule{
}

// bootstrap the app
platformBrowserDynamic().bootstrapModule(AppModule);

OpaqueTokenを使用して、モジュール性を改善し、型の依存関係を削除できます。

export const errorHandlerToken = new OpaqueToken('ErrorHandler');

モジュール内:

    providers: [
        // using OpaqueTokens you can change the provided value
        // to anything without changing consumer code 
        {provide: errorHandlerToken, useClass: ErrorHandler},

コンストラクタ:

    constructor(@Inject(errorHandlerToken) errorHandler: ErrorHandler) {
18
Distagon

Angular DIはコンストラクター注入のみをサポートします。つまり、コンストラクターが必要です。

抽象クラスはインスタンス化可能ではないため、抽象クラスに直接注入することもできません。

したがって、次のようにする必要があります。

export abstract class BaseApiComponent<T> {
    constructor(errorHandler: ErrorHandler) {}

    someMethod() {
     this.errorHandler.test();
    }
}

export class ApiComponentImpl<T> {
    constructor(errorHandler: ErrorHandler) {
      super(errorHandler);
    }

}
8

私はangular開発者ではありませんが、例を見ると、_@Inject_デコレータは パラメータデコレータ としてではなく、 プロパティデコレータ

2つのデコレータのタイプが異なるため、問題が発生する可能性がありますが、わかりません。
試してください:

_export abstract class BaseApiComponent<T> {
    private errorHandler: ErrorHandler;

    protected constructor(@Inject(ErrorHandler) handler) {
        this.errorHandler = handler;
    }

    public error() {
        this.errorHandler.test();
    }
}
_

また、実際にthis.errorHandler.test();を使用しているのかどうかはわかりません。クラスに配置することができないため、errorメソッドに移動しました。


編集する

正しい。拡張クラスに注入してから、インスタンスを親に渡す必要があります。

_export abstract class BaseApiComponent<T> {
    protected errorHandler: ErrorHandler;

    protected constructor(handler: ErrorHandler) {
        this.errorHandler = handler;
    }
}

export class Restaurants extends BaseApiComponent<any> {
    constructor(@Inject(ErrorHandler) handler) {
        super(handler);
    }
}
_
2
Nitzan Tomer