我想在Angular 2(这是一个普通的TypeScript文件)中加载具有WebAPI EndPoints的常量文件。 在Angular1.x中。我们曾经有过相同的常数。 如何在Angular 2中实现相同的目标?
我创建了.ts文件。我主要关注的是如何在每个其他类文件加载时预先加载文件。
.ts文件:
export class testAPI {
getAPI = "myUrl";
}
在服务文件中我通过正常导入使用相同的东西:
constructor(private http: Http) {
//console.log(this.test);
console.log(this.testing.getAPI);
//this.test.load();
}
我将控制台视为未定义。(必须是因为我的Service类在API类之前加载)。
先谢谢。
答案 0 :(得分:10)
<强>更新强>
启发了针对此特定问题的解决方案,创建了ngx-envconfig包,并将其发布在NPM注册表中。它具有与本答案中提供的功能相同的功能,甚至更多。
您可以将JSON文件放在assets文件夹中的某个位置,例如:$agentPhone = types_render_field( "agent-phone" );
$agentEmail = types_render_field( "agent-email" );
$agentFax = types_render_field( "agent-fax" );
。根据环境是否开发,您可以使用两个assets/config
文件,一个用于开发,一个用于生产。因此,您可以拥有.json
和development.json
个文件,其中每个文件都会保留相应的API端点。
基本上你需要完成以下步骤:
在production.json
文件夹中创建两个文件:
<强> environment.prod.ts 强>
src/environments
<强> environment.ts 强>
export const environment = {
production: true
};
<强> 资产/配置/ production.json 强>
export const environment = {
production: false
};
<强> 资产/配置/ development.json 强>
{
"debugging": false,
"API_ENDPOINTS": {
"USER": "api/v1/user",
...
}
}
注意,根据环境,{
"debugging": true,
"API_ENDPOINTS": {
"USER": "api/v1/user",
...
}
}
将加载相应的文件
ConfigService
import { Injectable, APP_INITIALIZER } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs';
import { environment } from 'environments/environment'; //path to your environment files
@Injectable()
export class ConfigService {
private _config: Object
private _env: string;
constructor(private _http: Http) { }
load() {
return new Promise((resolve, reject) => {
this._env = 'development';
if (environment.production)
this._env = 'production';
console.log(this._env)
this._http.get('./assets/config/' + this._env + '.json')
.map(res => res.json())
.subscribe((data) => {
this._config = data;
resolve(true);
},
(error: any) => {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
});
});
}
// Is app in the development mode?
isDevmode() {
return this._env === 'development';
}
// Gets API route based on the provided key
getApi(key: string): string {
return this._config["API_ENDPOINTS"][key];
}
// Gets a value of specified property in the configuration file
get(key: any) {
return this._config[key];
}
}
export function ConfigFactory(config: ConfigService) {
return () => config.load();
}
export function init() {
return {
provide: APP_INITIALIZER,
useFactory: ConfigFactory,
deps: [ConfigService],
multi: true
}
}
const ConfigModule = {
init: init
}
export { ConfigModule };
现在,您可以在任何地方使用ConfigService,获取config import { NgModule } from '@angular/core';
import { ConfigModule, ConfigService } from './config/config.service';
@NgModule({
imports: [
...
],
providers: [
...
ConfigService,
ConfigModule.init(),
...
]
})
export class AppModule { }
文件中定义的必要API端点。
答案 1 :(得分:6)
可以在TypeScript中导入JSON。你需要添加打字:
typings.d.ts:
declare module "*.json" {
const value: any;
export default value;
}
然后像这样导入:
import config from "../config/config.json";
config.json:
{
"api_url": "http://localhost/dev"
}
答案 2 :(得分:4)
在使用Angular CLI生成的Angular 4+项目中,您将直接使用environment
文件夹。在其中,您可以从Karlen的答案中找到environment.ts文件。需要注意的是,这是一种可行的配置解决方案:在构建时就捕获了环境变量。
为什么重要? 在为Angular应用程序设置CI / CD管道时,通常会使用一个构建工具来构建项目(例如Jenkins)和一个部署工具(例如Octopus)来抓取该程序包(dist文件夹),部署到选定的环境,并在此过程中用正确的值替换您的环境变量。如果使用environment.ts文件,则无法以这种方式替换您的环境变量,因为environment.ts文件未包含在dist文件夹中。您的部署工具无法拾取和编辑文件。
我们该怎么办?我们可以在assets
文件夹中添加一个JSON配置文件。这些文件默认包含在我们要部署的dist文件夹中。当我们要使用环境变量时,我们只需导入诸如import config from '[relative/path/to/your/config/file.json]'
之类的设置。
这样做时,我们会收到类似以下错误的信息:
Cannot find module '../../config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension
这是因为打字稿编译器尝试导入导出的模块而找不到该模块。我们可以通过在tsconfig.json
文件中添加以下JSON属性/值来解决此问题。
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
resolveJsonModule
允许打字稿编译器导入,从中提取类型并生成.json文件。
allowSyntheticDefaultImports
允许从模块进行默认导入,而没有默认导出。
有了这个,我们可以运行我们的项目,发现错误已经消失,我们可以使用配置值而没有任何问题。
现在,由于此配置文件包含在服务器上已部署的dist
文件夹中,因此我们可以配置部署工具,以将变量值替换为要部署到的环境的特定值。有了此功能,我们可以构建一次Angular应用并将其部署到任何地方。
另一个额外的好处是,大多数部署工具(如Octopus)都附带了本机JSON支持,因此您可以对其进行配置,以非常轻松地替换JSON文件中的环境变量。另一种选择是使用正则表达式解决方案替换.ts
文件中的环境变量,该文件相对更复杂且容易出错。
答案 3 :(得分:2)
我有同样的问题,最后我放弃了.ts并将它放入.js:D这样:
root中的configuration.js
var configuration = {
'apiHost': 'http://localhost:8900',
'enableInMemoryWebApi': false,
'authMode': 'standalone',
'wsUrl': 'ws://localhost:8900/ws'
};
module.exports = configuration;
在.ts文件中为ex。 user.service.ts
let configuration = require('../configuration'); //in import section
@Injectable()
export class UserService {
...
getUser(id: number | string): Promise<User> {
console.log(configuration.apiHost) //will get propertye from .js file
return this.http.get(`${configuration.apiHost}/${id}`, this.headers).toPromise().then(this.extractData).catch(this.handleError);
}
}
希望有所帮助
答案 4 :(得分:0)
您可以使用Opague token将常量值设置为提供商
尝试: 在你的const文件中:
import { OpaqueToken } from '@angular/core';
export const CONFIG_TOKEN = new OpaqueToken('config');
export const CONFIG = {
apiUrl: 'myUrl'
};
在AppModule中设置为使其成为应用程序的单一提供者:
providers:[
//other providers,
{provide: CONFIG_TOKEN, useValue: CONFIG}
]
对于构造函数中的注入,
constructor( @Inject(CONFIG_TOKEN) private config)
答案 5 :(得分:0)
是的,我做了@karlen
我的app.module.ts具有与上述类似的模式。
AppConfiguration,
{provide:APP_INITIALIZER,useFactory:initConfig, deps:[AppConfiguration],multi:true}
仍然存在与其他服务尝试从文件加载AppConfiguration之前注入值的问题相同的问题