我希望部署一个angular应用的生产版本,并为用户提供可配置的api url以进行测试。我使用environment.ts文件,但在生产版本构建后,我不知道如何配置变量。
需要采取什么方法?
我希望部署一个angular应用的生产版本,并为用户提供可配置的api url以进行测试。我使用environment.ts文件,但在生产版本构建后,我不知道如何配置变量。
需要采取什么方法?
import {Inject, Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Observable} from 'rxjs/Rx';
import {environment} from "../../environments/environment";
/**
* Declaration of config class
*/
export class AppConfig
{
//Your properties here
readonly production: boolean;
readonly name: string;
readonly apiBaseUrl: string;
}
/**
* Global variable containing actual config to use. Initialised via ajax call
*/
export let APP_CONFIG: AppConfig;
/**
* Service in charge of dynamically initialising configuration
*/
@Injectable()
export class AppConfigService
{
constructor(private http: HttpClient)
{
}
public load()
{
return new Promise((resolve, reject) => {
let confName = environment.name + '.json';
this.http.get('/assets/config/' + confName).map(res => res as any).catch((error: any): any => {
reject(true);
return Observable.throw('Server error');
}).subscribe((envResponse :any) => {
let t = new AppConfig();
//Modify envResponse here if needed (e.g. to ajust parameters for https,...)
APP_CONFIG = Object.assign(t, envResponse);
resolve(true);
});
});
}
}
第三步:在主模块中,在声明模块之前添加以下内容:
/**
* Exported function so that it works with AOT
* @param {AppConfigService} configService
* @returns {Function}
*/
export function loadConfigService(configService: AppConfigService): Function
{
return () => { return configService.load() };
}
第四步:修改模块提供者以添加此内容 提供者: [ …
AppConfigService,
{ provide: APP_INITIALIZER, useFactory: loadConfigService , deps: [AppConfigService], multi: true },
],
第五步: 在你的代码中,不要使用environment.configXXX,而是使用以下内容
import {APP_CONFIG} from "../services/app-config.service";
//…
return APP_CONFIG.configXXX;
这只是一个简化的例子,如果您使用Angular Universal,则需要进行一些更改,因为在进行HTTP调用时需要使用绝对URL。
src/
app/
environment/
environment.ts
environment.prod.ts
简单来说,只需在environment.prod.ts
中放置不同的URL地址,您的生产构建就会得到第二个URL地址。例如,假设您的environment.ts
文件如下:
{
"production": false,
"apiUrl": "http://localhost:8080"
}
environment.prod.ts
中:{
"production": true,
"apiUrl": "https://example.com/api"
}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { apiUrl } from '../environment/environment.ts';
@Injectable()
export class BackendService {
backendUrl: string = apiUrl;
constructor(private httpClient: HttpClient) {}
get(endpoint: string, params: any): Observable<any> {
const url= `${this.backendUrl}/${endpoint}`;
return this.httpClient.get(url, params);
}
}
简化后,但有效。默认情况下,您可以设置自己的URL。但是,您的组件可以即时设置URL,并从该URL获取其他内容。
现在,下一步是提供您拥有哪些后端。这可以是预配置的数组,或者您可以让客户自由输入URL(简单的输入框)。您可以有一个组件来完成此操作,并配置此服务。您可能还应该为“适当”的后端设置单独的服务,例如身份验证功能所在的服务。但这完全取决于您的情况。
除非我们需要一些异步调用来获取它们,否则我建议使用以下方法:
env.js
(function (window) {
window._env = window._env || {};
window._env.url= 'http://api-url.com';
}());
index.html
<head>
<script src="env.js"></script>
</head>
<body>
<app-root></app-root>
</body>
最后将其添加到angular.json中。
"assets": [
"any/env.js",