2016-06-30 8 views
2

これはおそらく特別なケースです(ブラウザのネイティブウィンドウオブジェクトを注入します)。しかし、私のクラスが@Injectable()デコレータをまだ持っている場合に@Inject()パラメータデコレータがなぜ必要なのか、少し混乱します。 なぜこのangular2の例で@injectが必要なのですか?

この簡略化した例を取る:

import { provide, bootstrap, Injectable, Inject } from '@angular/core'; 


@Injectable() 
export class Token { 
    private token: string; 

    public constructor(token: string, window: Window) { 
    this.token = window.atob(token); 
    }; 

    public getToken(): string { 
    return this.token; 
    } 
} 


@Injectable() 
export class TokenFactory { 
    private window: Window; 

    public constructor(window: Window) { 
    this.window = window; 
    } 

    public createToken(token: string): Token { 
    return new Token(token, this.window); 
    } 
} 


@Component({ 
    template: ` 
    <p *ngFor="let token of tokens"> 
     Encoded: {{token.getToken()}} 
    </p> 
    `, 
    providers: [ TokenFactory ] 
}) 
class MainComponent { 
    public tokens: Token[]; 

    public constructor(factory: TokenFactory) { 
    this.tokens = [ 
     factory.create('token-1'), 
     factory.create('token-2') 
    ]; 
    }; 
} 


bootstrap(
    MainComponent, [ 
    provide(Window, { useValue: window }) 
]); 

概要:我々は、コンポーネントまたは別のサービス(SOないシングルトン)の内部に複数回存在する可能性がオブジェクトを表すトークンクラスを有しています。トークンクラスは、グローバルウィンドウオブジェクト(base64エンコーディングなど)に依存します。 これをテスト可能にするには、グローバルでwindow objectのアプリケーション全体のプロバイダを、トークンサービスで直接使用するのではなく、ブートストラップ時に定義します。

メインコンポーネントは動的にトークンを作成する必要があるため、単純な工場サービスTokenFactoryを作成してインジェクトします。これにはウィンドウプロバイダも必要です(構築中にトークンクラスに渡す必要があります)。

問題:エラー

Can't resolve all parameters for TokenFactory: (?). 

なく工場コンストラクタウィンドウパラメータに@Inject(ウィンドウ)デコレータを添加することによって固定することができるブラウザで実行されるとき、これは失敗します。

ほとんどのガイド/チュートリアルでは、注入式デコレータで装飾を装飾する際に、注入装飾が必要ないことを説明しています。なぜ、@Inject()デコレータ

設定:emitDecoratorMetadataexperimentalDecoratorsの設定が有効になっていると私はTSC 1.8.10angular2 rc.3を使用しています。


PS:私はまた、一般的な設計改善のために開いています。

(例えば、生産シナリオでは、私はおそらく唯一のトークン・インターフェースではなくクラス全体をエクスポートします)

+0

Windowクラスがどこで定義され、どのようにインポートするかについてもっと教えてください。ありがとう! –

+0

そのグローバルな[ウィンドウオブジェクト](https://developer.mozilla.org/en-US/docs/Web/API/Window)は_window_(恋人の場合)として公開されています。ブートストラップの最中に注入されます。 Hm ...、typescript/angularがWindow nameプロパティを混乱させる可能性があるので、プロバイダー名は文字列か、この場合OpaqueTokenでなければなりませんか? – TomKeegasi

+0

これはコンパイル時(tsc)でないランタイム(ブラウザ)エラーです... – TomKeegasi

答えて

5

それは疑問が実際にあるものについて私には不明だが、

タイプstring用リク注射用のコンストラクタパラメータは、@Inject(...)

@Injectable() 
export class Token { 
    private token: string; 

    public constructor(token: string, window: Window) { // <<== invalid 
    this.token = window.atob(token); 
    }; 

    public getToken(): string { 
    return this.token; 
    } 
} 

せずに任意の意味がありませんが、あなたはそれを使用しているためe

new Token(token, this.window); 

これはちょうど@Injectable()がこのクラスから削除されるようです。エラーメッセージについて


Windowが正しくインポートされていないように見えますか、それはタイプが、 OpaqueTokenstringではありません。

@Inject()は、依存性注入によってパラメータタイプと異なるキーを使用する必要がある場合に必要です。あなたのケースでは、Windowは型(クラス)ではないため、そのように使われても機能しません。

+3

_token_パラメータが意図されていないので、トークンクラスの注射可能な部分を削除する必要があります。実際にはより多くの入力パラメータが必要になります。 _object_ウィンドウはブラウザーから来ているので(メタデータなし)、装飾されていない(メタデータなし)ため、ファクトリウィンドウパラメーターのInjectドクターレーターが必要です。右に聞こえる。 – TomKeegasi

関連する問題