2017-10-20 3 views
0

私は特定のデータへのアクセスを提供するAngular 4サービスを構築しています。このサービスが最初に をインスタンス化するときは、非同期プロセスであるデータストアへの接続を確立する必要があります。アングル4サービス:どのように非同期initプロセスを実装できますか?

は、どのように私は最高のこの非同期接続処理が完了する前にサービスを利用しようとするから(すなわち、コンポーネントやその他のサービス)このサービスの消費者を防ぐことができますか?

私のサービスが、この約束が解決するのを待つように、アンジェラのブートストラップに指示する方法はありますか?

サービスは、providersの配列に登録されています。 (私が理解しているように)Angularはサービスの単一インスタンスを構築し、MyServiceを注入するコンポーネントやサービスに提供されます。

明確にするために、ここで私が怖いシナリオです:アプリケーションのブートストラッププロセス中に

  1. は、角度は、モジュールのproviders配列でMyServiceを見て、そのコンストラクタを呼び出します。

  2. MyServiceのコンストラクタが接続プロセスを開始します。接続プロセスは2〜3秒かかる場合があります。

  3. 一方、Angularのブートストラップは先に充電を続け、アプリケーションのダッシュボードをレンダリングします。

  4. ダッシュボードコンポーネントはMyServiceを注入し、(それ自身のコンストラクタで、又はおそらくngOnInitで)接続が確立される前myService.getData()を呼び出そう。説明するために

、ここでは、このサービスは次のようになります。あなたの接続が確立されるまで、あなたが何をする必要があるか

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

@Injectable() 
export class MyService { 

    private connection; 

    constructor() { 

     this.connect().then((connection) => { 
      this.connection = connection; 
      // Components should be able to consume this service once execution reaches this point, but not before! 
     }); 

    } 

    private connect(): Promise<any> { 
     // (return some promise which will eventually resolve with a connection) 
    } 

    public getData(key: string): string { 
     // (this method won't be usable until the .then() in the constructor has run) 
    } 


} 
+0

なぜ、getData()から約束またはObservableを返さないのですか?それはおそらくあなたがどうにかしなければならないことでしょう。なぜなら、私は接続を使ってデータストアからデータを取得することが、非同期になることを推測しているからです。 –

+0

それはいい考えです、それはやるべきことかもしれません。実際、データアクセスは非同期ではありません(驚くほど十分です)。だから私が上記のことをやる方法があれば、データアクセスロジックをもっとシンプルに保つことが望ましいでしょう。アイデアをありがとう。 – greenie2600

+1

私はフレームワークレベルでそういうものを認識していません。しかし、ルーターを使用して親ルートに解決策を追加することで、ルーターが約束が満たされるまでサブ・ルートをナビゲートすることを防ぐことができます。 –

答えて

0

は、遅延アプリの初期化です。あなたは戻ってPlunker!!

onAppInit工場初期化約束

完全な以下のようなAPP_INITIALIZERトークンを使用してそれを行うことが

export function onAppInit(svc: MyService):() => Promise<any> { 
    return svc.initialize; 
} 

AppModule

@NgModule({ 
    imports:  [ BrowserModule ], 
    declarations: [ AppComponent ], 
    providers: [ 
    MyService, 
    { 
     provide: APP_INITIALIZER, 
     useFactory: onAppInit, 
     deps: [MyService], 
     multi: true 
    } 
    ], 
    bootstrap: [ AppComponent ] 
}) 
export class AppModule { } 

たMyService

@Injectable() 
export class MyService{ 
    connection; 

    constructor(){} 

    initialize =(): Promise<any> => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      this.connection = { 
      data : { 
       "var1": "xyz" 
      } 
      }; 
      resolve(); 
     }, 3000); 
    }); 
    } 

    getData =() => { 
    console.log(this.connection); 
    return this.connection.data; 
    } 
} 

AppComponent

@Component({ 
    selector: 'my-app', 
    template: `<h1>Hello</h1> 
    <hr /> 
    {{data | json}} 
    ` 
}) 
export class AppComponent { 
    data; 
    constructor(private svc: MyService){ } 

    ngOnInit(){ 
    this.data = this.svc.getData(); 
    } 
} 

これは、あなたの問題に尋ねたとして動作しますが、サービスが初期化されるまで、アプリケーションが表示されませんのでご注意、それは悪いユーザー体験もありどれくらいの遅延が許容できるかによって異なります。

もっと良い解決策はret @JBNizetがコメントで示唆したように、getData()からの約束またはObservableを返す。

これが役立ちますように!

関連する問題