- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在创建一个将使用 webApi 的 Angular2 应用程序。处理配置数据的最佳实践是什么?我想要一种在部署到不同环境时进行转换的方法。
在本地工作时,webApi 将是本地的,例如:http://localhost:64551/Api/person .
在开发中它将是: http://devServer.com/Api/person
产品将是: http://prodServer.com/Api/person
我无法对服务器名称进行硬编码。我在配置中需要它,但当我们部署到不同的环境时它会发生变化。
这是我使用 Visual Studio 在 ASP.net 5 项目中构建的 Anglar2 项目。WebApi 是一个 ASP.net 5 项目。我将在 Azure 上托管。
过去,我使用过 web.config 转换,但这不是 Angular 应用程序的选项。
有什么建议吗?
最佳答案
这可以通过使用 API 请求在 Angular 应用程序引导期间检索配置来解决。我个人认为 Angular 应该采取这种方法,因为要求开发人员为每个环境进行构建并不是最好的解决方案。
使用 Assets 中的配置文件:
像这样创建不同的配置文件夹/文件
使用正确的值填充这些 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"
}
...
这会将 Assets 移动到服务将用于检索 json 的位置。
创建一个利用 XMLHttpRequest 的配置服务(无法注入(inject) http,因为它需要在 Angular 引导之前运行)。请注意 get 请求如何访问 asset/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
关于azure - 带转换的 Angular2 配置数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34753195/
运行 PostgreSQL(7.4 和 8.x),我认为这是可行的,但现在我遇到了错误。 我可以单独运行查询,它工作得很好,但如果我使用 UNION 或 UNION ALL,它会抛出错误。 这个错误:
我试图为我的应用程序创建一个导航,使用抽屉导航我的 fragment 之一(HomeFragment)有一个 ViewPager,可容纳 3 个 fragment (Bundy Clock、Annou
以我目前正在开发的应用为例: - 它有一个包含多个项目的抽屉导航;现在有两个项目让我感兴趣,我将它们称为 X 和 Y。 X 和 Y 都在单击时显示包含 x 元素或 y 元素列表的 fragment 选
我有一个形状为 (370,275,210) 的 NumPy 数组,我想将其重新整形为 (275,210,370)。我将如何在 Python 中实现这一点? 370是波段数,275是行数,210是图像包
我们如何与被子 UIViewController 阻止的父 UIViewController(具有按钮)交互。显然,触摸事件不会通过子 Nib 。 (启用用户交互) 注意:我正在加载默认和自定义 NI
我是 Jpa 新手,我想执行过程 我的代码如下 private static final String PERSISTENCE_UNIT_NAME = "todos"; private static
与安装了 LAMP 的 GCE 相比,选择与 Google Cloud SQL 链接的 GCE 实例有哪些优势? 我确定 GCE 是可扩展的,但是安装在其上的 mysql 数据库的可扩展性如何? 使用
这个问题在这里已经有了答案: Value receiver vs. pointer receiver (3 个答案) 关闭 3 年前。 我刚接触 golang。只是想了解为 Calc 类型声明的两种
我不小心按了一个快捷键,一个非常漂亮的断线出现在日期上。 有点像 # 23 Jun 2010 -------------------- 有人知道有问题的快捷方式吗?? (我在 mac 上工作!) 在
我正在Scala中编写正则表达式 val regex = "^foo.*$".r 这很好,但是如果我想做 var x = "foo" val regex = s"""^$x.*$""".r 现在我们有
以下 XML 文档在技术上是否相同? James Dean 19 和: James Dean 19 最佳答案 这两个文档在语义上是相同的。在 X
我在对数据帧列表运行稳健的线性回归模型(使用 MASS 库中的 rlm)时遇到问题。 可重现的示例: var1 <- c(1:100) var2 <- var1*var1 df1 <- data.f
好的,我有一个自定义数字键盘,可以在标签(numberField)中将数字显示为 0.00,现在我需要它显示 $0.00。 NSString *digit = sender.currentTitle;
在基于文档的应用程序中,使用 XIB 文件,创建新窗口时其行为是: 根据最后一个事件的位置进行定位和调整大小 window 。 如果最后一个事件窗口仍然可见,则新窗口 窗口应该是级联的,这样它就不会直
我想使用参数进行查询,如下所示: SELECT * FROM MATABLE WHERE MT_ID IN (368134, 181956) 所以我考虑一下 SELECT * FROM MATABLE
我遇到一些性能问题。 我有一个大约有 200 万行的表。 CREATE TABLE [dbo].[M8]( [M8_ID] [int] IDENTITY(1,1) NOT NULL,
我在 jquery 中的按键功能遇到问题。我不知道为什么按键功能不起作用。我已经使用了正确的 key 代码。在我的函数中有 2 个代码,其中包含 2 个事件键,按一个键表示 (+) 代码 107 和(
我想显示音频波形,我得到了此代码,它需要.raw音频输入并显示音频波形,但是当我放入.3gp,.mp3音频时,我得到白噪声,有人可以帮助我如何使其按需与.3gp一起使用使用.3gp音频运行它。 Inp
我无法让 stristr 函数返回真值,我相信这是因为我的搜索中有一个 $ 字符。 当我这样做时: var_dump($nopricecart); 完整的 $nopricecart 值是 $0 ,我得
如果我有这样的循环: for(int i=0;i O(n) 次。所以do some执行了O(n)次。如果做某事是线性时间,那么代码片段的复杂度是O(n^2)。 关于algorithm - 带 If 语
我是一名优秀的程序员,十分优秀!