首页 > 解决方案 > 在 Angular 6 中加载配置文件

问题描述

我正在尝试了解如何在 Angular 6 中加载配置文件,我目前有一个 ConfigureService,其中包含用于加载文件的以下代码:

configUrl = '../assets/config.json';
config: Config;

load() {
  console.log('loading configuration');
  this.getConfig().subscribe(
    (data: Config) => {
      console.log('Config request success');
      (this.config = data);
      console.log(this.config)
    }
  );
}

private getConfig() {
  return this.http.get<Config>(this.configUrl);
}

在 ConfigureService 的构造函数中调用 load

我使用此服务为我的 api 消费者服务获取我的 Url 字符串,它确实运行成功(控制台.logs 显示在开发窗口中),只是没有及时让这些服务在其 OnInit 方法中使用其相应的 url 字符串,其他服务在尝试从未定义的配置对象中提取字符串时抛出错误。

我试图通过在 app.module 中指定它们并在启动之前加载它们来读取它们,如下所示:

https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9

然而,当我尝试该方法时,它告诉我在服务器上找不到文件,并且控制台中的错误返回 404,即使指定的路径是正确的。

如何确保配置服务首先运行,以便依赖它的其他服务在完成初始化之前不会尝试检索数据?

标签: angularangular6

解决方案


这是一个非常好的问题,我们也有不同的服务器(Dev、QC、Stage、Prod),因此为每个环境创建单独的构建是非常耗时的过程,我从未尝试过为每个环境创建单独的环境文件的方法, 我们通过将 Api Urls 和常量存储在 json 文件中解决了这个问题。

所以首先创建一个 json 文件并将其放在assets文件夹中。

配置文件

{
    "url":{
    "apiUrl": "http://localhost:58357/"
    }
}

创建一个模型类,它应该具有与Config.json文件同名的属性

配置文件

 export class Config {
    url: {
        apiUrl: string;
    };
}

创建服务以导入Config.json文件

app.config.service.ts

import { Injectable } from '@angular/core';
import { Config } from './models/config';
import { HttpClient, HttpBackend, HttpResponse } from '@angular/common/http';
import { Observable } from '../node_modules/rxjs';
import { map } from 'rxjs/operators';

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

static Settings: Config;
private http: HttpClient;
constructor(private httpBackEnd: HttpBackend) {
    this.http = new HttpClient(httpBackEnd);
}
load() {
    const jsonFile = 'assets/config.json';
    return new Promise<void>((resolve, reject) => {
    this.http.get(jsonFile).toPromise().then((response: Config) => {
       AppConfig.Settings = <Config>response;
       resolve();
    }).catch((response: any) => {
       reject(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`);
    });
    });
 }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppComponent } from './app.component';
import { AppConfig } from '../app.config.service';
import { HttpClientModule } from '../../node_modules/@angular/common/http';


export function initConfig(appConfig: AppConfig) {
return () => appConfig.load();
}

@NgModule({
declarations: [
AppComponent
],
  imports: [
  BrowserModule,
  HttpClientModule,
  ],
providers: [
 AppConfig, { provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfig], multi: true },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

在要使用存储在 json 文件中的密钥的任何组件文件中导入 AppConfig。

app.component.ts

import { Component } from '@angular/core';
import { AppConfig } from '../app.config.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
 })
 export class AppComponent {
 title = 'ConstantsManagerDemo';
 constructor() {
 const apiUrl = AppConfig.Settings.url.apiUrl;
 alert(apiUrl);
  }
 }

转到tsconfig.json文件并添加

"allowSyntheticDefaultImports" :true,  
under compilerOptions

推荐阅读