1. 程式人生 > >Angular:在應用初始化時運行代碼

Angular:在應用初始化時運行代碼

return none 方法 audio then 分享圖片 ini AR 資料

想象一下,您的應用需要一些動態配置信息,這些信息在應用啟動之前需要動態獲取,並在應用運行中使用。

顯然不能直接寫道靜態配置文件中,但是從客戶端發出的請求又是一個異步請求,如何協調這個問題呢?

這裏,我想向您演示,如何在 Angular 應用初始化期間,使用 APP_INITIALIZER 註入器來獲取應用的動態配置信息。

什麽是 APP_INITIALIZER 註入器

APP_INITIALIZER 是允許您在 Angular 初始化七千處理您自己任務的機制。它既可以用於 AppModule,核心模塊,也可以用於您自己的應用加載模塊中。典型的場景是應用加載之前做的事情,比如從服務處加載用於設置應用的配置信息。在示例中,我們使用它從服務器的 XML 配置文件中加載應用的設置信息。

創建 AppLoad 模塊

盡管不是必要,通過創建 App Load module 還是對應用加載有助於隔離。

import { NgModule, APP_INITIALIZER } from @angular/core;
import { HttpClientModule } from "@angular/common/http";
 
import { AppLoadService } from ./app-load.service;
 
export function init_app(appLoadService: AppLoadService) {
    
return () => appLoadService.initializeApp(); } export function get_settings(appLoadService: AppLoadService) { return () => appLoadService.getSettings(); } @NgModule({ imports: [HttpClientModule], providers: [ AppLoadService, { provide: APP_INITIALIZER, useFactory: init_app, deps: [AppLoadService], multi:
true }, { provide: APP_INITIALIZER, useFactory: get_settings, deps: [AppLoadService], multi: true } ] }) export class AppLoadModule { }

註意一下幾點:

  • APP_INITIALIZER 導入自 @angular/core
  • 這裏有多個 APP_INITIALIZER,它們在應用初始化過程中並發執行,直到它們全部完成。
    •   使用 nulti: true 用於多個註入器,如果只有一個,使用 multi: false。
  • 工廠函數 init_app 和 get_settings 應當返回一個返回 Promise 的函數。
  • 該模塊必須添加到 AppModule 的導入數組中。

創建 App Load Service

AppLoadService 應當隔離您在應用初始化期間的作為。當然這不是必須的,您可以使用任何需要的服務。

這裏實現了兩個方法我們在前面代碼中使用的方法。在我們的 AppLoadModule 中作為依賴註入到提供器數組中。

import { Injectable } from @angular/core;
import { HttpClient } from @angular/common/http;
import rxjs/add/operator/toPromise;
 
import { APP_SETTINGS } from ../settings;
 
@Injectable()
export class AppLoadService {
 
  constructor(private httpClient: HttpClient) { }
 
  initializeApp(): Promise<any> {
    return new Promise((resolve, reject) => {
          console.log(`initializeApp:: inside promise`);
 
          setTimeout(() => {
            console.log(`initializeApp:: inside setTimeout`);
            // doing something
 
            resolve();
          }, 3000);
        });
  }
 
  getSettings(): Promise<any> {
    console.log(`getSettings:: before http.get call`);
    
    const promise = this.httpClient.get(http://private-1ad25-initializeng.apiary-mock.com/settings)
      .toPromise()
      .then(settings => {
        console.log(`Settings from API: `, settings);
 
        APP_SETTINGS.connectionString = settings[0].value;
        APP_SETTINGS.defaultImageUrl = settings[1].value;
 
        console.log(`APP_SETTINGS: `, APP_SETTINGS);
 
        return settings;
      });
 
    return promise;
  }
}

註意以下幾點:

  • initializeApp 用於等待 3 秒,並輸出日誌來顯示兩個方法是並行執行的。
  • getSettings 調用一個模擬的我使用 APIARY 創建的 API 來或者設置。
    •   這裏使用這些設置來設置 APP_SETTINGS 對象的
  •   它們都返回 Promise

運行應用

運行應用,可以在 Console 中查看如下輸出

技術分享圖片

註意:

  • 您可以看到兩個方法都被調用了。
  • 設置首先返回
  • initializeApp 最後完成,然後應用啟動。

如何從 settings 中獲取 API 的地址?

有些人想:“如果沒有 settings 來知道 URL, 我如何調用 API 呢?”,這是一個問題,您可以通過一個相對 URL 來通過 HttpClient ,並假設 API 在您的 Web 站點上。

參考資料

https://www.intertech.com/Blog/angular-4-tutorial-run-code-during-app-initialization/

Angular:在應用初始化時運行代碼