簡體   English   中英

依賴注入抽象類的打字稿(Angular2)

[英]Dependency injection into abstract class 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

我怎么解決這個問題?

從Angular 2 RC5開始,DI變得更簡單。 你不需要用@Injectable()來裝飾東西。 相反,你只需在一個地方聲明DI - NgModule。

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) {

Angular DI僅支持構造函數注入,這意味着您需要構造函數。

您也不能直接注入抽象類,因為抽象類不應該是可實例化的。

因此它必須像:

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

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

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

}

我不是一個有角度的開發人員,但是看看這些例子,@ @Inject裝飾器總是被用作參數裝飾器而不是屬性裝飾器

由於兩個裝飾器類型不同,這可能會導致問題,但我不確定。
嘗試:

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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM