1

我有下一个提供者配置

  {
          provide: APP_INITIALIZER,
          useFactory: initializeKeycloak,
          multi: true,
          deps: [KeycloakService],
        },

如何从 useFactory 函数(initializeKeycloak)进行 HTTP 调用?

function initializeKeycloak(keycloak: KeycloakService) {

  return () =>
    keycloak.init({
      config: {
        url: environment.keycloak.url,
        realm: environment.keycloak.realm,
        clientId: environment.keycloak.clientId
      }
    });
}

我想从资产文件夹中获取这个值

environment.keycloak.url
4

1 回答 1

1

这里有两件事你需要知道:

  • 在您的asyncFactory函数中,您可以返回一个表示初始化完成时间的承诺。
  • 您可以将 . 添加HttpClientAPP_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$);
  };
};

附带说明:

虽然可以在启动时检索环境信息,但这有一个缺点,即如果请求失败,应用程序将根本无法加载。在这里添加重试机制可能是值得的。

还有一些方法可以在构建时注入环境变量,我在这个答案中提供了有关该主题的信息。

于 2020-11-20T22:41:53.160 回答