在Angular 2中加载配置JSON文件

Avi*_*ash 6 json typescript angular

我想在Angular 2(这是一个普通的TypeScript文件)中加载具有WebAPI EndPoints的常量文件.在Angular1.x中.我们曾经有过相同的常数.如何在Angular 2中实现相同的功能?

我创建了.ts文件.我主要关注的是如何在每个其他类文件加载之前加载文件.

.ts文件:

export class testAPI {
     getAPI = "myUrl";
}
Run Code Online (Sandbox Code Playgroud)

在服务文件中我通过正常导入使用相同的:

constructor(private http: Http) { 

      //console.log(this.test);
      console.log(this.testing.getAPI);
      //this.test.load();
    }
Run Code Online (Sandbox Code Playgroud)

我将控制台视为未定义.(必须是因为我的Service类在API类之前加载).

提前致谢.

Kar*_*len 13

更新

启发了针对此特定问题的解决方案,创建了ngx-envconfig包并将其发布在NPM注册表中.它具有与本答案中提供的功能相同的功能,甚至更多.


您可以将JSON文件放在assets文件夹中的某个位置,如:assets/config.根据环境是否开发,您可以使用两个.json文件,一个用于开发,一个用于生产.所以你可以拥有development.jsonproduction.json文件,每个文件都会保留适当的API端点.

基本上你需要完成以下步骤:

1.设置环境(如果已经有,请跳过此步骤)

src/environments文件夹中创建两个文件:

environment.prod.ts

export const environment = {
  production: true
};
Run Code Online (Sandbox Code Playgroud)

environment.ts

export const environment = {
  production: false
};
Run Code Online (Sandbox Code Playgroud)

2.创建JSON配置文件

资产/配置/ production.json

{
  "debugging": false,

  "API_ENDPOINTS": {
    "USER": "api/v1/user",
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

资产/配置/ development.json

{
  "debugging": true,

  "API_ENDPOINTS": {
    "USER": "api/v1/user",
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

3.按如下方式创建服务

注意根据环境,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 };
Run Code Online (Sandbox Code Playgroud)

4.与app.module.ts集成

import { NgModule } from '@angular/core';
import { ConfigModule, ConfigService } from './config/config.service';

@NgModule({
    imports: [
        ...
    ],
    providers: [
        ...
        ConfigService,
        ConfigModule.init(),
        ...
    ]
})

export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

现在,您可以在任何地方使用ConfigService,获取配置.json文件中定义的必要API端点.

  • 很好的答案!如果您想升级到 Angular 6 和 rxjs 6 API,请查看此内容:https://www.metaltoad.com/blog/angular-6-upgrading-api-calls-rxjs-6 (2认同)

Ale*_* Po 6

可以在TypeScript中导入JSON.你需要添加打字:

typings.d.ts:

declare module "*.json" {
  const value: any;
  export default value;
}
Run Code Online (Sandbox Code Playgroud)

然后像这样导入:

import config from "../config/config.json";
Run Code Online (Sandbox Code Playgroud)

config.json:

{
  "api_url": "http://localhost/dev"
}
Run Code Online (Sandbox Code Playgroud)


Kyl*_*son 6

在使用 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
Run Code Online (Sandbox Code Playgroud)

这是因为打字稿编译器尝试导入导出的模块但找不到。我们可以通过在我们的tsconfig.json文件中添加以下 JSON 属性/值来解决这个问题。

"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
Run Code Online (Sandbox Code Playgroud)

resolveJsonModule 允许打字稿编译器导入、提取类型和生成 .json 文件。

allowSyntheticDefaultImports 允许从没有默认导出的模块中默认导入。

有了这个,我们可以运行我们的项目,我们会发现我们的错误消失了,我们可以毫无问题地使用我们的配置值。

现在,因为此配置文件包含在dist部署在服务器上的文件夹中,所以我们可以配置我们的部署工具,用特定于我们要部署到的环境的值替换变量值。有了这个,我们可以一次构建我们的 Angular 应用程序并将其部署到任何地方

另一个额外的好处是,像 Octopus 这样的大多数部署工具都附带原生 JSON 支持,因此您可以很容易地配置它以替换 JSON 文件中的环境变量。另一种方法是使用正则表达式解决方案来替换.ts文件中的环境变量,这相对更复杂且容易出错。


Sur*_*Rao 0

您可以使用Opague 令牌将常量值设置为提供者

尝试:在你的 const 文件中:

import { OpaqueToken } from '@angular/core';

export const CONFIG_TOKEN = new OpaqueToken('config');
export const CONFIG = {
  apiUrl: 'myUrl'
};
Run Code Online (Sandbox Code Playgroud)

在您的 AppModule 中设置使其成为应用程序的单例提供程序:

providers:[
//other providers,
{provide: CONFIG_TOKEN, useValue: CONFIG}
]
Run Code Online (Sandbox Code Playgroud)

为了在构造函数中注入,

constructor( @Inject(CONFIG_TOKEN) private config)
Run Code Online (Sandbox Code Playgroud)