本文介绍了在 Angular 6 中加载配置文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

configUrl = '../assets/config.json';配置:配置;加载() {console.log('加载配置');this.getConfig().subscribe((数据:配置)=>{console.log('配置请求成功');(this.config = 数据);控制台.log(this.config)});}私有 getConfig() {返回 this.http.get(this.configUrl);}

在ConfigureService的构造函数中调用load的地方

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

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

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

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

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

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

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

Config.json

{网址":{"apiUrl": "http://localhost:58357/"}}

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

Config.ts

 导出类配置 {网址:{apiUrl:字符串;};}

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

app.config.service.ts

import { Injectable } from '@angular/core';从'./models/config'导入{配置};从@angular/common/http"导入 { HttpClient, HttpBackend, HttpResponse };从 '../node_modules/rxjs' 导入 { Observable };从'rxjs/operators'导入{地图};@Injectable({提供在:'根'})导出类 AppConfig {静态设置:配置;私有 http: HttpClient;构造函数(私有 httpBackEnd:HttpBackend){this.http = new HttpClient(httpBackEnd);}加载() {const jsonFile = 'assets/config.json';return new Promise((resolve, reject) => {this.http.get(jsonFile).toPromise().then((response: Config) => {AppConfig.Settings = <Config>response;解决();}).catch((response: any) => {拒绝(`无法加载文件'${jsonFile}':${JSON.stringify(response)}`);});});}}

app.module.ts

import { BrowserModule } from '@angular/platform-b​​rowser';从@angular/core"导入 { NgModule, APP_INITIALIZER };从 './app.component' 导入 { AppComponent };从 '../app.config.service' 导入 { AppConfig };从'../../node_modules/@angular/common/http'导入{HttpClientModule};导出函数 initConfig(appConfig: AppConfig) {返回 () =>appConfig.load();}@NgModule({声明: [应用组件],进口:[浏览器模块,HttpClient 模块,],供应商: [AppConfig, { 提供: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfig], multi: true },],引导程序:[AppComponent]})导出类 AppModule { }

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

app.component.ts

import { Component } from '@angular/core';从 '../app.config.service' 导入 { AppConfig };@成分({选择器:'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']})导出类 AppComponent {title = 'ConstantsManagerDemo';构造函数(){const apiUrl = AppConfig.Settings.url.apiUrl;警报(apiUrl);}}

转到 tsconfig.json 文件并添加

"allowSyntheticDefaultImports" :true,在编译器选项下

I'm trying to understand how to load configuration files in Angular 6, I currently have a ConfigureService with the following code for loading the file:

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);
}

Where load is called in the constructor of ConfigureService

I use this service to get my Url strings for my api consumer services, and it does run successfully (the console.logs show in the dev window), just not in time for those services to use their respctive url strings in their OnInit methods, and the other services throw errors as they are trying to pull the strings from an undefined config object.

I have tried to read them in by specifying them in the app.module and loading them before startup as seen here:

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

Yet when I try that method, it tells me that the files could not be found on the server, and the error in the console returns 404, even though the path specified is correct.

How can I ensure that the config service runs first so that other services who are dependent on it do not try to retrieve data before it has finished its initialization?

解决方案

It is a very good question,We too have different servers ( Dev, QC ,Stage ,Prod),so creating a separate build for every environment is very time consuming process ,I have never tried this approach of creating separate environment file for every environment,We solved this problem by storing the Api Urls and constants in a json file.

so first of all create a json file and place it inside assets folder.

Config.json

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

Create a model class which should have the properties with same name as is Config.json file

Config.ts

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

Create a service to import Config.json file

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 { }

import AppConfig in any component file where you want to use the keys stored in the json file.

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);
  }
 }

go to tsconfig.json file and add

"allowSyntheticDefaultImports" :true,
under compilerOptions

这篇关于在 Angular 6 中加载配置文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 09:51
查看更多