2

У нас есть новое приложение с угловыми углами, которое создает AOT в папку. Все работает нормально, но мы пытаемся настроить его на пятиэтапный процесс сборки с использованием TeamCity/Octopus Deploy, где каждый шаг будет использовать некоторые разные переменные для конечных точек (вызовы API и т. Д.). Я пытаюсь выяснить лучший способ передать это в приложение AOT, которое не отключается от бэкэнд.Угловые 2 и командные данные о производстве/окружающей среде города

Я знаю о флагом --environment, который может быть использован для запуска различных конфигураций, но наша цель состоит в том, чтобы иметь один построить все среды. Я не понимаю, как передавать переменные в приложении на основе среды, в которой он находится.

Моя идея состоит в том, чтобы оставить файл config.js в папке assets, чтобы приложение могло загрузить его до остальной части приложения и установите некоторые переменные в окне, но это оставляет мне проблему неспособности импортировать файл TS в файлы, которые нуждаются в этих переменных.

Как передать эту информацию в приложение более интуитивным способом? Разве это невозможно обойти без отдельных сборок?

ответ

2

Я хотел бы основываться на вашей идее config.js. Конфигурация должна быть загружена как часть запуска приложения, а не часть сборки. Вам нужно сделать сервис, который загружает config.js при запуске вашего приложения, использовать поставщика APP_INITIALIZER и передать ему фабрику, которая создает эту службу. Вот пример:

app.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core'; 

@NgModule({ 
    imports: [ 
     .... 
    ], 
    declarations: [ 
     .... 
    ], 
    providers: [ 
     { 
      provide: APP_INITIALIZER, 
      useFactory: configServiceFactory, 
      deps: [ConfigService, Http, AppConfig], 
      multi: true 
     }, 
     AppConfig, 
     ConfigService 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

конфигурации службы:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 

import { AppConfig } from '../../app.config'; 

@Injectable() 
export class ConfigService { 
    private _config: AppConfig; 

    constructor(private http: Http, private config: AppConfig) { 
    } 

    public Load(): Promise<AppConfig> { 
     return new Promise((resolve) => { 
      this.http.get('./config.json').map(res => res.json()) 
      .subscribe((config: AppConfig) => { 
       this.copyConfiguration(config, new AppConfig()).then((data: AppConfig) => { 
        this._config = data; 
        resolve(this._config); 
       }); 
      }, (error: any) => { 
       this._config = new AppConfig(); 
       resolve(this._config); 
      }); 
     }); 
    } 

    public GetApiUrl(endPoint: any): string { 
     return `${this._config.ApiUrls.BaseUrl}/${this._config.ApiUrls[ endPoint ]}`; 
    } 

    public GetApiEndPoint(endPoint: any): string { 
     return this._config.ApiUrls[ endPoint ]; 
    } 

    public Get(key: any): any { 
     return this._config[ key ]; 
    } 

    private copyConfiguration(source: Object, destination: Object): any { 
     return new Promise(function(resolve) { 
      Object.keys(source).forEach(function(key) { 
       destination[ key ] = source[ key ]; 
       resolve(destination); 
      }); 
     }); 
    } 
} 

export function configServiceFactory(config: ConfigService) { 
    return() => config.Load(); 
} 
+0

Святое дерьмо, это гениально. Я думаю, вы просто решили все мои проблемы. Я никогда не думал о захвате локального файла службой Http, и я никогда не знал об APP_INITIALIZER. Я собираюсь попробовать это сейчас, а потом, надеюсь, отметить это как решение :) Спасибо! – joh04667

+1

Отлично! Затем просто сделайте OctopusDeploy поместим нужный файл в нужную среду. –