这里有两件事你需要知道:
- 在您的
asyncFactory
函数中,您可以返回一个表示初始化完成时间的承诺。
- 您可以将 . 添加
HttpClient
到APP_INITIALIZER
. 请注意,您必须将其添加HttpClientModule
到您的导入中,AppModule
以便它可用于注入。
RxJS 6 的工作示例:
const initializeKeycloak = (
keycloakService: KeycloakService,
httpClient: HttpClient // The httpClient is available here because you added it to the deps of the APP_INITIALIZER
) => {
return () =>
httpClient
.get(url)
.pipe(
tap((environment: any) => {
keycloakService.init({
config: {
url: environment.keycloak.url,
realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId
}
});
})
)
.toPromise(); // Return the promise to indicate the initialization is done.
};
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule],
declarations: [AppComponent, HelloComponent],
bootstrap: [AppComponent],
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [KeycloakService, HttpClient] // Add the HttpClient here.
},
KeycloakService
]
})
export class AppModule {}
RxJS 7+ 的工作示例(toPromise 将被弃用,您必须使用 lastValueFrom):
import { lastValueFrom } from "rxjs";
...
const initializeKeycloak = (
keycloakService: KeycloakService,
httpClient: HttpClient
) => {
return () => {
const request$ = httpClient.get(url).pipe(
tap((environment: any) => {
keycloakService.init({
config: {
url: environment.keycloak.url,
realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId
}
});
})
);
return lastValueFrom(request$);
};
};
附带说明:
虽然可以在启动时检索环境信息,但这有一个缺点,即如果请求失败,应用程序将根本无法加载。在这里添加重试机制可能是值得的。
还有一些方法可以在构建时注入环境变量,我在这个答案中提供了有关该主题的信息。