1. ホーム
  2. typescript

[解決済み] Angular 2でアプリ起動時にサービスを実行する方法

2022-08-12 23:34:28

質問

SocketServiceというサービスを作りました。基本的にはソケットを初期化し、アプリがポートをリッスンできるようにします。このサービスはまた、いくつかのコンポーネントと相互作用します。

// socket.service.ts

export class SocketService {
    constructor() {
        // Initializes the socket
    }
    ...
}

SocketServiceのコンストラクタ()内のコードは、コンポーネントがSocketServiceを使用するときにのみ実行が開始されますね。

そして、通常app.tsのコードはこんな感じです。

// app.ts

import {SocketService} from './socket.service';
...
class App {
    constructor () {}
}
bootstrap(App, [SocketService]);

しかし、このサービスはアプリの起動時に実行させたい。そこで private _socketService: SocketService を追加するだけです。これで、コードは次のようになる。

// app.ts (新規)

import {SocketService} from './socket.service';
...
class App {
    constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);

これで動作するようになりました。問題は、SocketServiceのコンストラクタ()内のコードが実行されるときとされないときがあることです。では、どのようにすれば正しく動作するのでしょうか?ありがとうございます。

どのように解決するのですか?

Stuartの回答は正しい方向を示していますが、APP_INITIALIZERに関する情報を見つけるのは簡単ではありません。簡単に言うと、他のアプリケーション コードが実行される前に初期化コードを実行するために使用することができます。しばらく検索してみたところ、以下のような説明がありました。 ここで はこちら がありますが、ウェブ上から消えてしまうかもしれないので、まとめておきます。

APP_INITIALIZERはangular/coreで定義されています。このようにapp.module.tsにインクルードします。

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

APP_INITIALIZERは OpaqueToken (または Angular 4 以降の InjectionToken) で、ApplicationInitStatus サービスを参照しています。ApplicationInitStatusは マルチプロバイダ . これは複数の依存関係をサポートし、プロバイダリストの中で複数回使用することができます。使い方はこのようになります。

@NgModule({
  providers: [
    DictionaryService,
    {
      provide: APP_INITIALIZER,
      useFactory: (ds: DictionaryService) => () => return ds.load(),
      deps: [DictionaryService],
      multi: true
    }]
})
export class AppModule { }

このプロバイダ宣言は、ApplicationInitStatusクラスにDictionaryService.load()メソッドを実行するように指示しています。load()はプロミスを返し、ApplicationInitStatusはプロミスが解決されるまでアプリ起動をブロックするようになっています。load()関数はこのように定義されています。

load(): Promise<any> {
  return this.dataService.getDiscardReasons()
  .toPromise()
  .then(
    data => {
      this.dictionaries.set("DISCARD_REASONS",data);
    }
  )
}

辞書が最初に読み込まれるように設定し、アプリの他の部分が安全にそれに依存できるようにします。

編集: これは、load()メソッドにかかる時間だけ、アプリの最初のロード時間を増加させることに注意してください。 これを避けたい場合は リゾルバ を使うことができます。