在Angular中完成工厂异步功能后如何设置模块加载顺序?

时间:2019-04-30 06:24:14

标签: angular typescript

在加载应用程序之前,我使用 runtime-config-loader-lib.servise.ts 服务加载应用程序的设置,并为此使用 APP_INITIALIZER

>

该应用程序还使用 TranslateModule TranslateHttpLoader 从api加载翻译文件,在其中您需要使用应用程序设置文件中的一些参数

仅在config-loader返回配置文件后,如何才能启动 TranslateModule 的加载?

runtime-config-loader-lib.service.ts

import {Inject, Injectable, Optional, PLATFORM_ID} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Subject} from 'rxjs';
import {isPlatformBrowser} from '@angular/common';


@Injectable({providedIn: 'root'})
export class RuntimeConfigLoaderService {
  private configObject;
  public configSubject: Subject<any> = new Subject<any>();
  private baseConfigPatch = '/assets/data/appConfig.json';
  private fullConfigPatch: string;

  constructor(private _http: HttpClient,
              @Inject(PLATFORM_ID) private platformId: {},
              @Inject('APP_BASE_URL') @Optional() private readonly baseUrl: string) {
    this.fullConfigPatch = `${this.baseUrl}${this.baseConfigPatch}`;
    if (isPlatformBrowser(platformId)) {
      this.baseUrl = document.location.origin;
      this.fullConfigPatch = `${this.baseUrl}${this.baseConfigPatch}`;
    }
  }

  public loadConfig(): Promise<any> {
    return this._http
      .get(this.fullConfigPatch)
      .toPromise()
      .then((configData: any) => {
        this.configObject = configData;
        this.configSubject.next(this.configObject);
      })
      .catch((err: any) => {
        console.log(err);
        this.configObject = null;
        this.configSubject.next(this.configObject);
        this.configSubject.complete();
      });
  }

  public getConfig() {
    return this.configObject;
  }

  public getConfigObjectKey(key: string) {
    return this.configObject ? this.configObject[key] : null;
  }
}

app.module.ts

...
export function exportTranslateStaticLoader(http: HttpClient,
                                            transferState: TransferState,
                                            cookie: CookieService,
                                            configLoader: RuntimeConfigLoaderService) {
  return new TranslateBrowserLoader('', '.json', transferState, http, cookie, configLoader);
}

export function initConfig(configSvc: RuntimeConfigLoaderService) {
  return () => configSvc.loadConfig();
}
...

imports: [
    BrowserModule.withServerTransition({
      appId: 'loot-bet-app'
    }),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: exportTranslateStaticLoader,
        deps: [HttpClient, TransferState, CookieService, RuntimeConfigLoaderService]
      }
    })
  ],
  providers: [
    RuntimeConfigLoaderService,
    {
      provide: APP_INITIALIZER,
      useFactory: initConfig,
      deps: [RuntimeConfigLoaderService],
      multi: true,
    },
    {
      provide: ErrorHandler,
      useFactory: initSentryBrowser,
      deps: [RuntimeConfigLoaderService]
    },
    {provide: 'LOCALSTORAGE', useFactory: getLocalStorage},

  ],

translate-browser-loader.service.ts

import {Observable} from 'rxjs/Observable';
import {TranslateLoader} from '@ngx-translate/core';

import {makeStateKey, StateKey, TransferState} from '@angular/platform-browser';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {HttpClient} from '@angular/common/http';
import {CookieService} from 'ngx-cookie';
import {RuntimeConfigLoaderService} from '../runtime-config-loader/runtime-config-loader-lib.service';

export class TranslateBrowserLoader implements TranslateLoader {
  appConfig;

  constructor(private prefix: string = 'i18n',
              private suffix: string = '.json',
              private transferState: TransferState,
              private http: HttpClient,
              private cookie: CookieService,
              private configLoader: RuntimeConfigLoaderService) {
    this.getAppConfig();
  }

  public getTranslation(lang: string): Observable<any> {
    let apiUrl: string;
    let returnResult;

    if (this.appConfig.browser.symphonyApiUrl) {
      apiUrl = this.appConfig.browser.symphonyApiUrl;
    } else {
      const protocol = window.location.protocol;
      const host = window.location.host;
      apiUrl = `${protocol}//api.${host}`;
    }
    // API url address for loading translates files
    this.prefix = this.appConfig.remoteTranslate ? `${apiUrl}/cms/locale/` : '/assets/i18n/';

    // Set translate file lang from cookie or default value
    let setLang = lang || this.cookie.get('language') || 'en';

    // create transfer state key
    const key: StateKey<number> = makeStateKey<number>('transfer-translate-' + setLang);
    const translateDataFromTransferState = this.transferState.get(key, null);

    // if have translate file in Transfer State return this file
    if (translateDataFromTransferState) {
      returnResult = Observable.create(observer => {
        observer.next(translateDataFromTransferState);
        observer.complete();
      });
    } else {
      returnResult = new TranslateHttpLoader(this.http, this.prefix, this.suffix).getTranslation(setLang);
    }
    return returnResult;

  }

  private getAppConfig(): void {
    this.configLoader.configSubject.subscribe((configData) => {
      this.appConfig = configData;
    });
  }

}

0 个答案:

没有答案