2017-01-04 10 views
3

angular-cli私はdeploydバックエンドで使用したいプロジェクトを生成しました。 Deploydには、http://<deployd-host>/dpd.jsからロード可能なAPIにアクセスするためのスクリプトが用意されています。これにより、グローバルなオブジェクトが作成され、javascriptのグローバルコンテキスト(例:Chrome開発ツールコンソールから)からAPIにアクセスできます。Angular2サービスでの外部スクリプトのラップ

これをAngular2サービスでラップしてテストなどのための模擬テストを挿入することができます。タスクはURLからスクリプトを読み込んでから、グローバルdpdオブジェクトにアクセスすることです。私はthisの投稿を見ましたが、受け入れられた回答を得ることができませんでした。 documentオブジェクトに手動でスクリプトを追加すると、windowのdpdオブジェクトにアクセスできません。

また、スクリプトが読み込まれるURLは、環境に応じて異なります(例:ローカルのdevの場合はhttp://localhost:3000/dpd.js、ステージングの場合はhttp://dev.example.com/dpd.js、プロダクションの場合はです。理想的には、サービスでもそれを設定できるようになります。

以下のようなものをお探しですか?

@Injectable() 
export class DpdService { 
    constructor() { 
    if (getEnvironmentSomeHow() == 'development') { 
     loadScriptFrom("http://localhost:3000/dpd.js"); 
    } else { 
     loadScriptFrom("http://dev.example.com/dpd.js"); 
    } 
    dpd = window.dpd; 
    } 

    public session(): Observable<Session> { 
    return Observable.fromPromise(dpd.sessions.get()); 
    } 
} 
+0

いくつかのコードを共有できます –

+0

可能な複製:http://stackoverflow.com/questions/39942118/how-to-inject-different-service-based-on-certain-build-environment-in-angular2/39942256#39942256コード – Karl

+0

による非常に詳細な説明あなたが質問に示したアプローチの問題は何ですか? – estus

答えて

1

アプリケーション環境は、開発者の選択に完全に依存します。これらは、ノード環境変数に依存するTSファイルを条件付きで含むことができます。クライアント側のグローバル変数(Webpack DefinePluginまたはEnvironmentPluginで提供される可能性が高い、たとえばangular2-webpack-starterを参照)に応じてAngularプロバイダを定義する単一のファイルにすることができます。その最も単純な形式ではそれだけで、クライアント側のグローバルENV変数である、すべての決定は、その場で作られています - それも、サーバー側のテンプレートでHTMLに設定することができます。

<script> 
    window.ENV = <% SERVER_SIDE_ENV_VARIABLE %> 
</script> 

ためのスクリプトその事実に

... 
import {APP_INITIALIZER} from '@angular/core' 
import {DOCUMENT} from '@angular/platform-browser' 

@Injectable() 
export class DpdService { 
    dpd: any; 

    constructor(@Inject(DOCUMENT) document: Document) {} 

    load() { 
    const srcBase = window.ENV === 'dev' 
     ? 'http://localhost:3000/' 
     : 'http://dev.example.com/'; 

    const script = this.document.createElement('script'); 
    this.document.body.appendChild(script); 

    return new Promise((resolve, reject) => { 
     script.onload = resolve; 
     script.onerror = reject; 
     script.async = true; 
     script.src = srcBase + 'dpd.js'; 
    }).then(() => { 
     this.dpd = window.dpd; 
    }); 
    } 

    session(): Observable<Session> { 
    return Observable.fromPromise(this.dpd.sessions.get()); 
    } 
} 

export function dpdAppInitializerFactory(dpdService: DpdService) { 
    return() => dpdService.load(); 
} 

... 
providers: [ 
    DpdService, 
    { 
    provide: APP_INITIALIZER, 
    useFactory: dpdAppInitializerFactory, 
    deps: [DpdService], 
    multi: true 
    } 
], 
アプリが初期化された時点で

...

は、load方法から約束が果たされると:アプリの初期化時にロードする必要があり、それはAPP_INITIALIZER multiproviderにロードする必要がありますプロパティが設定されています。

+0

それは素晴らしい作品です。いくつかのもの... 'DpdService.load()'は 'dpdService.load()'でなければなりません。また、この後、 'シンボル値を静的に解決する際にエラーが発生しました。関数呼び出しはサポートされていません。関数またはラムダをエクスポートされた関数(元の.tsファイルの23:19の位置)への参照で置き換え、シンボルAppModuleを解消することを検討してください。 –

+0

環境に関しては、これは環境を管理する必要がある 'angular-cli 'を使用しています。 –

+0

エラーは 'aot'の問題であるようです...解決策とは何も関係がありません。 –

関連する問題