APP_INITIALIZER 是 InjectionToken的一个实例。它是 Angular 提供的内建注入令牌。

Angular会在利用加载时执行这个令牌提供的函数。如果函数返回promise,那么angular会始终期待,直到promise被解析。这将使它成为在应用程序初始化之前执行一些初始化逻辑的现实地位。

Angular 注入器应用 DI 令牌来定位 Angular providers 中的依赖项。咱们应用令牌在提供者中注册依赖项:

providers :[{ provide: token, useClass: SomeService }]

下面代码里的 token,能够是一个 type,一个字符串,或者是 InjectionToken 的一个实例。

  • type 的例子:
providers :[{ provide: productService, useClass: productService}]
  • 字符串的例子:
providers :[ {provide:'MESSAGE', useValue: 'Hello Angular'}]

当所应用的类型没有运行时示意时,例如注入接口、可调用类型(callable type) 等,就会应用 InjectionToken - TypeScript 代码里的 interface,被编译成 JavaScript 之后,后者从编程语言层面不存在 interface 这种 representation. 此时能够应用 InjectionToken.

export const HELLO_MESSAGE = new InjectionToken<string>('Hello Angular'); providers :[ { provide: HELLO_MESSAGE, useValue: 'Hello World!' }];

如前所述,APP_INITIALIZER在应用程序初始化时运行。Angular会暂停利用的初始化,直到APP_INITIALIZER提供的所有函数运行结束。如果其中任何一个初始化器返回一个promise,那么angular就会期待它的解析,而后再持续进行App的初始化。

这使咱们有机会连贯到初始化过程并运行一些应用程序自定义逻辑。能够加载运行时配置信息。从后盾加载重要数据等。

看一个例子。新建文件 app-init.service.ts

import { Injectable }  from '@angular/core'; @Injectable()export class AppInitService {     constructor() {    }        Init() {         return new Promise<void>((resolve, reject) => {            console.log("AppInitService.init() called");            ////do your initialisation stuff here              setTimeout(() => {                console.log('AppInitService Finished');                resolve();            }, 6000);         });    }}

app.module.ts 的实现:

import { BrowserModule } from '@angular/platform-browser';import { NgModule, APP_INITIALIZER } from '@angular/core';import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component';import { AboutUsComponent } from './about-us.component';import { HomeComponent } from './home.component';import { ContactUsComponent } from './contact-us.component'; import { AppInitService } from './app-init.service'; export function initializeApp1(appInitService: AppInitService) {  return (): Promise<any> => {     return appInitService.Init();  }} @NgModule({  declarations: [    AppComponent, AboutUsComponent,HomeComponent,ContactUsComponent  ],  imports: [    HttpClientModule,    BrowserModule,    AppRoutingModule,  ],  providers: [     AppInitService,    { provide: APP_INITIALIZER,useFactory: initializeApp1, deps: [AppInitService], multi: true}  ],  bootstrap: [AppComponent]})export class AppModule { }

下面的代码,应用了 InjectionToken APP_INITIALIZER 来提供函数 initializeApp1,后者调用了咱们 service class 的 init 办法。

Angular的依赖注入会把依赖注入到类和组件中,但不会注入到函数中。而咱们的initializeApp1是一个函数,须要将AppInitService作为参数注入。因而咱们通过应用 deps 标记来做到这一点,并让 Angular 晓得它须要创立一个AppInitService的实例,并将它注入到initializeApp1函数中。

multi: true 创立 multi provider DI 令牌。这意味着能够为DI令牌提供提供程序数组。

如果 multi: false(默认值)被设置并且屡次应用一个令牌,最初注册的将令牌将笼罩之前所有的令牌。也就是说,令牌只能有一个 provider.