Angular 5に、Injectableのコンストラクター内で使用されるPromiseが解決されるのを待ってから、依存関係(またはngOnInit)を構築するにはどうすればよいですか?

Dai

Angular 5プロジェクトに、いくつかの構成状態を保持するサービスがあります。

@Injectable
export class FooService {

    isIncognito: boolean = null;

    constructor() {

        // I want Angular to wait for this to resolve (i.e. until `isIncognito != null`):
        FooService.isIncognitoWindow()
            .then( isIncognito => {

                this.isIncognito= isIncognito;
            } );
    }


    private static isIncognitoWindow(): Promise<boolean> {
    // https://stackoverflow.com/questions/2909367/can-you-determine-if-chrome-is-in-incognito-mode-via-a-script
    // https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem

        return new Promise<boolean>( ( resolve, reject ) => {

            let rfs = window['requestFileSystem'] || window['webkitRequestFileSystem'];
            if( !rfs ) {
                console.warn( "window.RequestFileSystem not found." );
                resolve( false );
            }

            const typeTemporary = 0;
            const typePersistent = 1;

            // requestFileSystem's callbacks are made asynchronously, so we need to use a promise.
            rfs(
                /*type: */ typeTemporary,
                /* bytesRequested: */ 100,
                /* successCallback: */ function( fso: WebKitFileSystem ) {

                    resolve( false );
                },
                /* errorCallback: */ function( err: any /* FileError */ ) {

                    resolve( true );
                }
            );
        } );
    }
}

このサービスは、私のプロジェクトの多くのコンポーネントで使用されており、コンストラクター引数として渡されます。例えば:

@Component( {
    moduleId: module.id,
    templateUrl: 'auth.component.html'
} )
export class AuthComponent implements OnInit {

    constructor( private fooService: FooService ) {
    }

    ngOnInit(): void {

        // do stuff that depends on `this.fooService.isIncognito != null`
    }
}

理想的には、Angularが他のコンポーネントFooService::isIncognitoWindow()にを注入する前に、最初に約束が解決されるのを待って(解決は即座に行われますが、同期は行われません)したいと思いFooServiceます。

別の解決策はFooComponent.isIncognito、のプロパティをに変更し、Promise<boolean>それを再度解決しngOnInitて、コールバック介して残りを呼び出すことですが、これは、すべてのコンポーネントがPromiseのメイン関数を再度呼び出すことを意味します-つまり、バッファリングされたObservableまたは代わりに主題、そしてそれは不必要に複雑になっています-すべて単一のboolean値のために。また、私が行う必要のない多くのコードをリファクタリングすることも意味します。

デビッド

できることは、APP_INITIALIZERトークンを使用してFooService、アプリケーションが起動する前にが初期化されていることを確認することです以下のコードでは、angularはloadメソッドによって返されたpromiseが解決されたときにのみアプリケーションを開始します

FooService.ts

@Injectable()
export class FooService {

    isIncognito: boolean = null;

    public load()// <=== the method to be called and waited on during initialiation
  {
      return FooService.isIncognitoWindow().then(isIncognito =>
      {
        this.isIncognito = isIncognito;
      });

  }

    private static isIncognitoWindow(): Promise<boolean> {
    { //your method here

app.module.ts

export function loadFooService(fooService: FooService): Function 
{
  return () => { return fooService.load() }; 
}


@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ],

  providers: [ FooService,
  { provide: APP_INITIALIZER, useFactory:loadFooService , deps: [FooService], multi: true },]
})

stackblitzの例を参照してください

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ