我想部署一个角度应用程序的生产版本,其中包含一个可配置的API,供用户测试。我使用environment.ts但是在生成构建之后,我不知道如何配置变量。
需要采取什么方法?
答案 0 :(得分:8)
环境* .ts文件包含构建时配置,构建后无法更改。如果您需要在构建后更改配置,则需要将它们放在不同的位置并在应用程序启动时动态检索它们
你能做的是:
步骤#1 :将您的json配置文件放在src / assets / config / [envName] .json下。
注意:它必须是json格式,而不是ts格式
第2步:添加新配置服务
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);
});
});
}
}
第3步:在主模块中,在声明模块之前添加此项
/**
* Exported function so that it works with AOT
* @param {AppConfigService} configService
* @returns {Function}
*/
export function loadConfigService(configService: AppConfigService): Function
{
return () => { return configService.load() };
}
步骤#4 :修改模块提供程序以添加此项 提供者:[ ...
AppConfigService,
{ provide: APP_INITIALIZER, useFactory: loadConfigService , deps: [AppConfigService], multi: true },
],
第5步:在您的代码中,不要使用environment.configXXX,请使用此
import {APP_CONFIG} from "../services/app-config.service";
//…
return APP_CONFIG.configXXX;
这是一个简化的示例,如果您使用angular universal,您实际上需要进行一些更改,因为您在进行http调用时需要使用绝对URL
答案 1 :(得分:6)
您使用的是Angular-CLI吗?那应该很容易。你有这样的事情:
src/
app/
environment/
environment.ts
environment.prod.ts
只需将不同的网址放在environment.prod.ts
中,您的prod版本就会获得第二个网址。例如。让我们说你的environment.ts
看起来像这样:
{
"production": false,
"apiUrl": "http://localhost:8080"
}
将其放入environment.prod.ts
:
{
"production": true,
"apiUrl": "https://example.com/api"
}
您可以设置更多环境,检查.angular-cli.json
和angular-cli repo的部分。
修改:根据您的评论,您需要更多内容。
是的,但在构建之后仍然无法配置吗?因为我不知道用户想要使用的url因此我想在部署构建后从外部对其进行配置。
让我们继续这种情况。让我们有一个后端客户端:
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(只需输入框)。您可以拥有一个可以执行此操作的组件,并在此处配置此服务。您可能还应该为您的&#34;正确的&#34;提供单独的服务。后端,例如,你的认真谎言。但这一切都取决于你的情况。
答案 2 :(得分:3)
答案 3 :(得分:0)
好吧,除非我们需要一些异步调用来获取它们。否则,我建议这样做:
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",
现在,您可以使用应用程序中的服务来读取窗口