Angular 如何在启动时执行初始化代码
首先介绍APP_INITIALIZER
APP_INITIALIZER
是一个InjectionToken
,是Angular默认提供的。在之前的AngularJs
中,每一个能被注入的Service都会有一个InjectionToken来标记,从这个细节来看,在Angular中大概也是这样的思路。
在NgModule的providers属性中,可以用一个token和一个class来标记能被注入的service:
provider:[{provide:token,useClass:YourServece}];
//or
providers:[ {provide:'MESSAGE', useValue: 'Hello Angular'}];
//or
export const MESSAGE = new InjectionToken<string>('Hello Angular');
providers :[ { provide: HELLO_MESSAGE, useValue: 'Hello World!' }];
//这里的token可以是string或者某种type,或者是InjectionToken的一个实例
那么显而易见的思路是:将APP_INITIALIZER
这个token与想要执行的初始化逻辑绑定。Angular会将绑定的逻辑在App初始化的时候执行,如果这段逻辑返回的是一个Promise,Angular会一直等待Promise完成后再进行之后的工作。
来一段真实代码看看
import { BrowserModule } from '@angular/platform-browser';
import {APP_INITIALIZER, NgModule} from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {UIKitModule} from "./uikit/uikit.module";
import {ServicesModule} from "./services/services.module";
import {init} from 'leancloud-storage';
const initLeancloud=()=>{
return ()=>{init({appId:'xxxxx',appKey:'xxxxxx'});}
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
UIKitModule,
ServicesModule,
AppRoutingModule,
],
providers: [
{provide:APP_INITIALIZER,useFactory:initLeancloud,multi:true},
],
bootstrap: [AppComponent]
})
export class AppModule { }
这里有几个比较奇怪的地方:
- useFactory:当你的逻辑是一个function的时候就用这个字段,当时angular推荐你用class。
- multi:如果是true,说明这个provideToken可以被重复使用,如果是false,就说明只能用一次。那么什么是反复使用呢?看看下面这段代码。
providers: [
{provide:APP_INITIALIZER,useFactory:initLeancloud,multi:true},
{provide:APP_INITIALIZER,useFactory:otherFunction,multi:true},
],
显然很明显,这个APP_INITIALIZER
被使用了两次,这两个function都会在Angular启动的时候执行,从上到下。此时,如果multi是false,那么下面的function就会把上面的覆盖。
需要注意的是,使用useFactory的时候,所指定的function一定要有return值,并且return要返回一个函数。
网友评论