繁体   English   中英

注入配置服务时未定义的配置

[英]Undefined config when injecting a config service

这是我之前的帖子的后续。 我已经调试这个问题很长一段时间了,尽管我还没有解决它,但我发现了一些东西,所以也许有人能提供帮助。

这是整个设置:
app-config.json (/src/assets/):

{
  "apiUrl": "localhost:8080"
}

app-config.service.ts (/src/app/):

import {Injectable, Injector} from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class AppConfigService {

  private appConfig: any;

  constructor (private injector: Injector) { }

  loadAppConfig() {
    let http = this.injector.get(HttpClient);

    return http.get('/assets/app-config.json')
      .toPromise()
      .then(data => {
        this.appConfig = data;
      })
  }

  get config() {
    return this.appConfig;
  }

}

应用程序模块.ts (/src/app/):

import {APP_INITIALIZER, NgModule} from '@angular/core';
import {HttpClientModule} from '@angular/common/http';
import {AppConfigService} from './app-config.service';
import {CometdService} from './cometd/cometd.service';

const appInitializerFn = (appConfig: AppConfigService) => {
  return () => {
    return appConfig.loadAppConfig();
  }
};

@NgModule({
...
  providers: [HttpClientModule,
    AppConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: appInitializerFn,
      multi: true,
      deps: [AppConfigService]
    }]
})

export class AppModule {
  constructor(cometdService: CometdService) {}
}

cometd.service.ts (/src/app/cometd/):

import {Injectable, OnDestroy} from '@angular/core';
import {Store} from '@ngrx/store';
import * as fromRoot from '../reducers';
import {AppConfigService} from '../app-config.service';

export interface CometDExtended extends cometlib.CometD {
  websocketEnabled: boolean;
}

@Injectable({
  providedIn: 'root'
})
export class CometdService implements OnDestroy {

  protected cometd: CometDExtended = new cometlib.CometD() as CometDExtended;

  private subscriptions: cometlib.SubscriptionHandle[] = [];

  constructor(private environment: AppConfigService, private store: Store<fromRoot.State>) {
    let config = environment.config;
    let apiUrl = environment.config.apiUrl;
    
    this.cometd.configure('http://localhost:8080/cometd');
    this.startConnection();
  }
...
}
  • 各种服务都会出现此问题。 CometD 只是一个例子。
  • app-config.service.ts 本身的数据被正确获取,即 loadAppConfig() 返回 { "apiUrl": "localhost:8080" }。
  • 注入环境 (AppConfigService) 已定义,即它的类型为 Object。
  • environment.config 未定义,因此 environment.config.apiUrl 返回错误:“TypeError:无法读取未定义的属性(读取‘apiUrl’)”。

providers 数组中不需要AppConfigService ,因为providedIn: 'root'已经使它可用。

如果您以不同的方式提供服务,您可能有多个实例:一个将被加载,其他则不会。

如果还是不行,打个断点看看在init完成之前是否有其他服务被创建。 我建议将调用移出 CometdService 构造函数,这样您就可以以干净的方式执行异步调用

好吧,在发布问题几分钟后,我碰巧找到了解决方案。 似乎因为 loadAppConfig() 是异步的,所以在解析 promise 之前可能已经访问了 environment.config。 将构造函数更改为:

this.environment.loadAppConfig().then(() => {
let config = environment.config
...
});

解决了这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM