Ionic2/Angular2 - 读取自定义配置文件

Ionic2/Angular2 - Read a custom config file

我正在处理一个 ionic2 项目,我需要创建一个新的自定义 JSON 配置文件。我找到了一些创建一个并通过 http.get 访问它的教程,但我认为通过 get 请求调用它很奇怪。我希望它位于根文件夹(所有配置 JSON 所在的位置)并且我直接 open/read 文件。

我不知道这是否可行,甚至推荐?这就是为什么我在这里发布一些意见和解决方案的原因:)

谢谢

个人不喜欢读取config.json文件,使用http.get的方式来处理配置信息,虽然必须有的另一种方法是在您的代码中包含并读取 json 文件,因为我们使用的是 Angular2 和 Typescript,为什么不使用 类、接口并执行它以更奇特的方式?

接下来我将向您展示的内容可能看起来比一开始看起来更复杂(尽管在阅读之后您会发现它非常简单易懂),但是当我开始学习 Angular2 时,我看到了一个示例如何他们在 Dependency Injection guide 中处理了 配置文件 ,我在处理配置信息(如 API 端点、默认值和很快)。

根据文档:

Non-class dependencies

[...]

Applications often define configuration objects with lots of small facts (like the title of the application or the address of a web API endpoint) but these configuration objects aren't always instances of a class.

One solution to choosing a provider token for non-class dependencies is to define and use an OpaqueToken

因此您需要使用 url 等定义配置对象,然后 OpaqueToken 才能在使用您的配置注入对象时使用它。

我在 app-config.ts 文件中包含了所有配置

// Although the ApplicationConfig interface plays no role in dependency injection, 
// it supports typing of the configuration object within the class.
export interface ApplicationConfig {
  appName: string;
  apiEndpoint: string;
}

// Configuration values for our app
export const MY_CONFIG: ApplicationConfig = {
  appName: 'My new App',
  apiEndpoint: 'http://www...'
};

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken('config');

什么是OpaqueToken 一开始可能会让人困惑,但它只是一个字符串,可以在注入这个对象时避免命名冲突。关于这个 here.

你可以找到一个惊人的 post

然后,你只需要像这样将它包含在你需要的页面中:

import { NavController } from 'ionic-angular/index';
import { Component, OpaqueToken, Injectable, Inject } from "@angular/core";

// Import the config-related things
import { MY_CONFIG_TOKEN, MY_CONFIG, ApplicationConfig } from 'app-config.ts';

@Component({
  templateUrl:"home.html",
  providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
})
export class HomePage {

  private appName: string;
  private endPoint: string;

  constructor(@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig) {
    this.appName = config.appName;
    this.endPoint = config.apiEndpoint;
  }
}

请注意如何将其包含在 providers 数组中

providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]

以及如何告诉注入器它应该如何获取配置对象的实例

@Inject(MY_CONFIG_TOKEN) config: ApplicationConfig

更新

OpaqueToken 自 v4.0.0 以来已被弃用,因为它不支持类型信息,请改用 InjectionToken<?>

所以代替这些行:

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

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken('config');

现在我们应该使用

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

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new InjectionToken<ApplicationConfig>('config');

在阅读和阅读不同的解决方案后,我最终使用了这个 hacky 实现。希望很快会有一个不错的原生解决方案可用:

import { NgModule } from '@angular/core';
import { environment as devVariables } from './environment.dev';
import { environment as testVariables } from './environment.test';
import { environment as prodVariables } from './environment.prod';

export function environmentFactory() {
  const location = window.location.host;
  switch (location) {
    case 'www.example.org': {
      return prodVariables;
    }
    case 'test.example.org': {
      return testVariables;
    }
    default: {
      return devVariables;
    }
  }
}

@NgModule({
  providers: [
    {
      provide: 'configuration',
      useFactory: environmentFactory
    }
  ]
})
export class EnvironmentsModule {}

然后在需要的地方,例如:

import { Injectable, Injector, Inject } from '@angular/core';

import { AuthenticationService } from '../authentication';

@Injectable()
export class APIService {

  private http: Http;
  private apiURL: string;
  protected authentication: AuthenticationService;

  constructor(
    public injector: Injector,
    @Inject('configuration') public configuration: any
  ) {
    this.http = injector.get(Http);
    this.authentication = injector.get(AuthenticationService);
    this.apiURL = configuration.apiURL;    
  };

...