如何将服务的HTTP响应数据传递至app.module.ts
解决方案
你的问题核心是如何在APP_INITIALIZER加载完配置后,让app.module里的工厂函数能访问到这些配置数据。我们可以通过以下几步实现:
步骤1:修改GlobalSettingsService,存储加载的配置数据
首先要让服务把获取到的配置保存下来,而不是只resolve一个布尔值,这样后续的工厂函数就能拿到这些数据:
import { Injectable, Inject } from '@angular/core'; import { Http } from '@angular/http'; @Injectable() export class GlobalSettingsService { apiUrl: string; // 新增属性存储配置数据 appConfig: { googleClientId: string; reCaptchaKey: string } | null = null; constructor( private http: Http, @Inject(ORIGIN_URL) private baseUrl: string, @Inject(API_PREFIX) private apiPrefix: string ) { this.apiUrl = this.baseUrl + this.apiPrefix; } load() { return new Promise((resolve, reject) => { this.http .get(this.apiUrl + 'bootstrap') .map(res => res.json()) .subscribe({ next: (response) => { console.log(response); // 将配置存入服务属性 this.appConfig = response; resolve(true); }, error: (err) => { console.error('加载全局配置失败', err); reject(err); } }); }); } }
步骤2:修改AuthServiceConfig的工厂函数,注入GlobalSettingsService
现在可以在getUserAuthServiceConfigs里注入GlobalSettingsService,直接使用它存储的配置数据。因为APP_INITIALIZER已经确保在应用初始化前完成配置加载,所以appConfig一定是有值的:
export function getUserAuthServiceConfigs(globalSettings: GlobalSettingsService) { const config = new AuthServiceConfig( [ { id: GoogleLoginProvider.PROVIDER_ID, provider: new GoogleLoginProvider(globalSettings.appConfig!.googleClientId) }, ] ); return config; }
步骤3:更新app.module里的Provider配置
需要给AuthServiceConfig的工厂函数添加依赖,让Angular能注入GlobalSettingsService,同时简化globalSettingsProviderFactory:
// 简化工厂函数,返回执行load的函数 export function globalSettingsProviderFactory(provider: GlobalSettingsService) { return () => provider.load(); } @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [ GlobalSettingsService, { provide: APP_INITIALIZER, useFactory: globalSettingsProviderFactory, deps: [GlobalSettingsService], multi: true }, { provide: AuthServiceConfig, useFactory: getUserAuthServiceConfigs, // 添加依赖,注入GlobalSettingsService deps: [GlobalSettingsService] }, { provide: ORIGIN_URL, useValue: '/' }, { provide: API_PREFIX, useValue: 'api/' } ], bootstrap: [AppComponent] }) export class AppModule { }
关键说明
- APP_INITIALIZER的作用:它会在应用初始化(包括启动组件、初始化Providers)之前执行指定的工厂函数,必须等到Promise resolve后才会继续初始化流程。所以我们可以确保
GlobalSettingsService.load()完成后,getUserAuthServiceConfigs才会执行。 - 非空断言的安全性:因为APP_INITIALIZER的Promise必须resolve才会继续应用初始化,所以
globalSettings.appConfig一定不会是null,这里用非空断言!是安全的。如果担心加载失败的情况,可以在load()方法里处理错误,比如抛出异常阻止应用启动,或者提供默认配置兜底。
内容的提问来源于stack exchange,提问作者Hoàng Nguyễn
相关产品推荐
相关产品推荐

