Angular2使用transform处理配置数据

5
我正在创建一个使用WebApi的Angular2应用程序。处理配置数据的最佳实践是什么?我想要一种在部署到不同环境时进行转换的方法。
当在本地工作时,WebApi将是本地的,例如:http://localhost:64551/Api/person
在开发环境中,它将是: http://devServer.com/Api/person 生产环境将是: http://prodServer.com/Api/person 我不能硬编码服务器名称。我需要它在配置中,但随着我们部署到不同的环境,它会改变。
这是一个Anglar2项目,我正在使用Visual Studio内的ASP.net 5项目构建它。 WebApi是一个ASP.net 5项目。 我将在Azure上托管。
过去,我使用了web.config转换,但这对于Angular应用程序不是一个选项。
有什么建议吗?

1
你的Angular应用程序和API是否从同一个服务器提供?如果是,那么你可以使用window.location.origin,它会根据运行位置的不同而在这三个值之间进行更改。 - Langley
1
不行。WebApi应用程序将是它自己的项目。这就是问题所在。如果它是同一个项目,我可以使用相对API名称。 - Don Chambers
我有同样的问题,可能可以通过使用主机名和私有虚拟网络来解决。在这种情况下,前端应用程序使用主机名(即mybackendserver/api/person),而不是公共IP地址。 - Gianpolo
2个回答

0

可以使用 API 请求在 Angular 应用程序引导期间检索配置来解决此问题。我个人认为,Angular 应该采取这种方法,因为要求开发人员为每个环境构建并不是最好的解决方案。

在 Assets 中使用配置文件:

创建不同的配置文件夹/文件,如下所示

  • /assets/configurations/develop/configuration.json
  • /assets/configurations/production/configuration.json

使用正确的值填充那些 configuration.json 文件。

{
  "production": false,
  "api": "https://dev.myapi.domain.com"
}

创建一个表示您配置的接口。
export interface InitConfiguration {
  production: boolean;
  api: string;
}

更新您的 angular.json(或 workspace.json 或 project.json)文件,以便服务使用正确的文件。此示例使用存储资产并将其拉入的共享库。请确保将 glob 应用于每个环境,下面仅显示 dev。

"targets": {
    "build": {
      "configurations": {
        "dev": {
          "assets": [
            {
              "glob": "**/*",
              "input": "./libs/shared/assets/",
              "output": "./assets"
            },
            {
              "glob": "configuration.json",
              "input": "./libs/shared/assets/configurations/develop",
              "output": "./assets/configurations"
            }
            ...

这将把资产移动到服务用于检索json的位置。

创建一个配置服务,利用XMLHttpRequest(无法注入http,因为它需要在angular引导之前运行)。请注意,get请求正在访问assets / configuration / configuration.json文件。

import { Injectable } from '@angular/core';
import { InitConfiguration } from './init-configuration';

/**
 * Service that provides configuration information from assets
 * Assets folder contains \{env}\configuration.json file that matches environment
 */
// @dynamic
@Injectable({ providedIn: 'root' })
export class InitConfigurationService<
  T extends InitConfiguration = InitConfiguration
  > {
  private static _configuration: InitConfiguration | undefined = undefined;
  static production = false;

  static loadConfig(): Promise<void> {
    return new Promise((resolve, reject) => {
      const req = new XMLHttpRequest();
      req.addEventListener('load', () => {
        if (req.status === 200) {
          try {
            InitConfigurationService._configuration = JSON.parse(
              req.responseText
            );
            this.production =
              InitConfigurationService._configuration?.production || false;
          } catch (e) {
            reject(e);
          }
          resolve();
        } else {
          reject(req.statusText);
        }
      });
      req.open('GET', '/assets/configurations/configuration.json');
      req.send();
    });
  }

  getConfiguration(): T {
    if (!InitConfigurationService._configuration) {
      throw new ReferenceError(
        `Attempting to access configuration before it is set.
         Possible Solutions:
          1. Bootstrap the loadConfig method into your applications main.ts
          InitConfigurationService.loadConfig().then(
            () => {
              return platformBrowserDynamic()
                .bootstrapModule(AppModule)
                .catch((err) => console.error(err));
            }
          )
        `
      );
    }
    return InitConfigurationService._configuration as T;
  }

  get production(): boolean {
    return InitConfigurationService.production;
  }

  get api(): string {
    return this.getConfiguration().api || '';
  }
}

最后,在调用bootstrapModule之前引导服务以运行loadConfig()。
InitConfigurationService.loadConfig().then(async () => {
  if (InitConfigurationService.production) {
    enableProdMode();
  }
  try {
    return platformBrowserDynamic().bootstrapModule(AppModule);
  } catch (err) {
    return console.error(err);
  }
});

这些步骤支持使用不同的服务配置提供不同的环境。当您去部署时,您将需要手动移动文件。只需在您的CD中引入类似于此的步骤即可。

copy my-angular-app\assets\configurations\develop\configuration.json my-angular-app\assets\configurations\configuration.json /Y

-1
  • 从Visual Studio添加多个解决方案配置 - debug,qa,prod

  • 在您的app/文件夹中添加特定于环境的配置文件

    • environment.debug.ts
    • environment.qa.ts
    • environment.prod.ts
  • app/文件夹内添加environment.ts文件。将您的配置数据添加到其中。将此文件导入不同的组件以供使用。

  • 要包含特定于环境的配置文件,请在Visual Studio项目属性的预构建事件中添加脚本

xcopy "app\config\environment.$(ConfigurationName).ts" "app\environment.ts" /Y


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接