我正在使用angular 5和httpclient。我不是内置环境的忠实粉丝来设置我需要消耗的环境api url。我已经切换到使用nginx.conf,我在其中进行api调用,返回一个json,其中包含从环境变量设置的api url。
我有一个服务,我正在进行http.get调用以获取json配置文件。
@Injectable()
export class ConfigurationService {
private baseUrl = 'https://someUrl.com';
constructor( private http: HttpClient ) {
}
getConfig(): Observable<any> {
return this.http
.get(this.baseUrl + '/config')
.map(res=>res);
};
}
当应用程序首次启动时,将从我的app.component.ts调用此服务。
我有一个constants.ts文件,我想用它来引用我的api urls
export class Constants {
public api1 = //NEED API1 URL FROM SERVICE HERE;
public api2= //NEED API2 URL FROM SERVICE HERE;
从服务中引入数据的最佳方法是什么?我的常量文件不仅仅是一个类的组件。
答案 0 :(得分:0)
您应该将constant
作为@Injectable
的类,并设置方法将值设置如下
@Injectable()
export class Constants {
api1 :string; // NEED API1 URL FROM SERVICE HERE;
api2: string; // NEED API2 URL FROM SERVICE HERE
setValueApi1(val){
this.api1 = val;
}
}
您可以将此注入构造函数并调用方法以通过传递响应来设置值,如下所示
@Injectable()
export class ConfigurationService {
private baseUrl = 'https://someUrl.com';
constructor( private http: HttpClient,private constants:Constants ) { }
getConfig(): Observable<any> {
return this.http
.get(this.baseUrl + '/config')
.map(res=>res)
}
}
在您的组件中,您可以订阅响应值并通过调用以下方法设置api值
this.getConfig().subscribe(response => {
this.constants.setValueApi1(response))
})
答案 1 :(得分:0)
对于类似的内容,您应该使用应用初始化服务。应用初始化程序会在应用程序中的所有其他内容之前运行,并且在完成之前,您的应用程序将无法加载。它的结构如下:
import { Injectable, APP_INITIALIZER } from '@angular/core';
export interface AppConfig {
api1: string;
api2: string;
}
@Injectable()
export class ConfigService {
protected config: AppConfig;
constructor(private _http: HttpClient) {
}
getConfigData(): Observable<any> {
return this._http.get<AppConfig>('... your config url...')
.catch(error => {
alert('Unable to read configuration file:' + JSON.stringify(error));
return Observable.throw(error);
});
}
public load() {
return new Promise((resolve, reject) => {
this.getConfigData()
.subscribe(
config => {
this.config= config ;
resolve(true);
},
err => resolve(err)
);
});
}
}
export function ConfigServiceInitFactory(configService: ConfigService) {
return () => configService.load();
}
export const ConfigServiceInitProvider = {
provide: APP_INITIALIZER,
useFactory: ConfigServiceInitFactory,
deps: [ConfigService],
multi: true
}
然后将ConfigServiceInitProvider与ConfigService一起添加到AppModule提供程序(在ConfigServiceInitProvider之前放置ConfigService),只需在需要的地方注入ConfigService并访问配置值,如:
constructor(private _config: ConfigService) {
this.apiBase = this._config.config.api1;
}
我不喜欢_config.config的重复性,所以我通常也会在我的配置服务上定义getters,如:
get api1() { return this.config.api1 }
然后你可以打电话:
this.apiBase = this._config.api1;
但是,如果你问是否可以在constants.ts文件中设置值,以便它可以像:
一样使用import {Constants} from 'app/constants';
constructor() {
this.apiBase = Constants.api1;
}
在运行时从服务器加载的内容无法完成,因为在运行构建命令时,所有的typescript都会编译为javascript。因此,您逻辑上无法使用从服务器加载的内容创建构建,而不将其作为服务值提供。您将始终必须注入服务。
解决这个问题的唯一方法是在运行构建之前插入不同的常量文件,然后您永远不需要从服务器调用配置。但这有它本身的缺点,例如它需要完全重建和重新部署以更新配置值,这首先是一种配置点。
答案 2 :(得分:0)
一种简单的方法就是这样:
class Constants {
public api1: string;
public api2: string;
public setApi1(api: string) {}
public setApi2(api: string) {}
}
export const CONSTANTS: Constants = {
api1: "DEFAULT API 1",
api2: "DEFAULT API 2",
setApi1(api: string) : void {
this.api1 = api;
},
setApi2(api: string) : void {
this.api2 = api;
}
}
然后只需在需要持久性的地方导入const
:
import {CONSTANTS} from "../path/to/constant.ts";