问题描述
我正在尝试了解如何在 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,即使指定的路径是正确的.
如何确保配置服务首先运行,以便依赖它的其他服务在完成初始化之前不会尝试检索数据?
所以首先创建一个json文件并将其放在assets文件夹中.
{网址":{"apiUrl": "http://localhost:58357/"}}
创建一个模型类,该类应该具有与Config.json 文件同名的属性
导出类配置 {网址:{apiUrl:字符串;};}
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)}`);});});}}
import { BrowserModule } from '@angular/platform-browser';从@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.
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);}}
"allowSyntheticDefaultImports" :true,在编译器选项下
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
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 中加载配置文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!