web-dev-qa-db-ja.com

Angular 2に構成JSONファイルをロード

Angular 2(通常のTypeScriptファイル)でWebAPI EndPointsを使用して定数ファイルをロードしたい。Angular1.xでは、同じ定数を使用していた。方法Angular 2同じを実装できますか?

私は.tsファイルを作成しました。私の主な関心事は、他のクラスFileがロードするたびに、事前にファイルをロードする方法にあります。

.tsファイル:

export class testAPI {
     getAPI = "myUrl";
}

サービスファイルでは、通常のインポートを実行して同じものを使用しています。

constructor(private http: Http) { 

      //console.log(this.test);
      console.log(this.testing.getAPI);
      //this.test.load();
    }

コンソールが未定義として表示されます(サービスクラスがAPIクラスの前に読み込まれていることが原因である可能性があります)。

前もって感謝します。

9
Avinash

[〜#〜]更新[〜#〜]

この特定の問題の解決策に触発されて作成された ngx-envconfig パッケージがNPMレジスターに公開されました。これは、この回答で提供されているものと同じ機能を備えています。


JSONファイルは、assets/configのようにアセットフォルダーのどこかに置くことができます。環境がdevであるかどうかに応じて、2つの.jsonファイルを使用できます。1つは開発用、もう1つは本番用です。そのため、development.jsonファイルとproduction.jsonファイルを使用でき、それぞれが適切なAPIエンドポイントを保持します。

基本的に、次の手順を実行する必要があります。

1.環境をセットアップする(既にある場合は、このステップをスキップします)

src/environmentsフォルダに2つのファイルを作成します。

environment.prod.ts

export const environment = {
  production: true
};

environment.ts

export const environment = {
  production: false
};

2. JSON構成ファイルを作成する

assets/config/production.json

{
  "debugging": false,

  "API_ENDPOINTS": {
    "USER": "api/v1/user",
    ...
  }
}

assets/config/development.json

{
  "debugging": true,

  "API_ENDPOINTS": {
    "USER": "api/v1/user",
    ...
  }
}

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

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

これで、config .jsonファイルで定義された必要なAPIエンドポイントを取得したい場所であればどこでもConfigServiceを使用できます。

9
Karlen

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"
}
5
Alex Po

私は同じ問題を抱えていて、結局私は.tsをあきらめて.js:Dに入れます:

ルートのconfiguration.js

var configuration = {
    'apiHost': 'http://localhost:8900',
    'enableInMemoryWebApi': false,
    'authMode': 'standalone',
    'wsUrl': 'ws://localhost:8900/ws'
};

module.exports = configuration;

exの.tsファイル。 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);
    }
}

それが役に立てば幸い

2
dev_in_progress

Angular Angular CLIで生成された4つ以上のプロジェクトでは、environmentフォルダーをそのまま使用できます。 Karlenの回答からenvironment.tsファイルが見つかります。これは、1つの注意点がある構成の実用的なソリューションです。環境変数はビルド時に取得されます。

なぜそれが問題なのですか? AngularアプリにCI/CDパイプラインを設定する場合、通常、プロジェクトをビルドするビルドツール( Jenkins)と、そのパッケージ(distフォルダー)を取得して選択した環境にデプロイするデプロイメントツール(Octopusなど)と、プロセス内の環境変数を正しい値に置き換えます。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

これは、TypeScriptコンパイラがエクスポートされたモジュールをインポートしようとし、それを見つけられないためです。これを修正するには、tsconfig.jsonファイルに次のJSONプロパティ/値を追加します。

"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,

resolveJsonModuleを使用すると、TypeScriptコンパイラで.jsonファイルをインポート、抽出、および生成できます。

allowSyntheticDefaultImportsは、デフォルトのエクスポートなしでモジュールからのデフォルトのインポートを許可します。

これで、プロジェクトを実行できるようになり、エラーがなくなり、問題なく構成値を使用できるようになります。

これで、この構成ファイルはサーバーに展開されるdistフォルダーに含まれるため、展開ツールを構成して、変数の値を、展開先の環境に固有の値に置き換えることができます。これを配置すると、Angularアプリを1回ビルドしてどこにでもデプロイするを作成できます。

もう1つの追加の利点は、OctopusなどのほとんどのデプロイメントツールにネイティブJSONサポートが付属しているため、JSONファイルの環境変数を非常に簡単に置き換えるように構成できることです。もう1つの方法は、正規表現ソリューションを使用して.tsファイル内の環境変数を置き換えることです。これは、比較的複雑で間違いが起こりやすいものです。

1
Kyler Johnson

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)
0
Suraj Rao