web-dev-qa-db-ja.com

Angular非同期ファクトリプロバイダー

非同期作業を行ってサービスを返すファクトリをセットアップし、そのファクトリをファクトリプロバイダーに提供して、コンポーネントがロードされたときにそのサービスをコンポーネントに提供したいと思います。

ただし、プロバイダーがTestServiceTestComponentに挿入する場合、実行時の型はZoneAwarePromiseです。プロバイダーがサービスをコンポーネントに注入する前に、プロバイダーがプロミスを自動的に「待機」する方法が必要です。

サービス

export class TestService {
 public test() {
   return 123;
 }
}

プロバイダーと工場

export function testFactory(auth: any, temp: any) {
  return new Promise((res, rej) => {
    res(new TestService());
  });
}

export let testProvider =
{
  provide: TestService,
  useFactory: testFactory,
  deps: []
};

アプリモジュール

providers: [
    testProvider
]

TestComponent

import { Component, OnInit } from '@angular/core';
import { TestService } from './Test';

@Component({
    selector: 'app-test'
})
export class TestComponent implements OnInit {
    constructor(private testService: TestService) { }

    async ngOnInit() {
        console.log(this.testService.test()); // fails because the type of this.testService at runtime is "ZoneAwarePromise" instead of "TestService"
    }
}
9
Sharpiro

Angularはプロバイダーの非同期ファクトリ関数を直接実装できないようです。

これを行うには、新しい関数を設定し、それをNgModuleに渡して、APP_INITIALIZERジョブを実行する必要があります。

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

function configFactory(testService: TestService) {
  // do the async tasks at here
  return () => testService.init()
}

@NgModule({
  providers: [
    {
      provide:      APP_INITIALIZER,
      useFactory:   configFactory,
      deps:         [TestService],
      multi:        true,
    },
  ],
})

関連項目

Angular4 APP_INITIALIZERは初期化を遅らせません

2
Huan