Загрузка файлов конфигурации в Angular 6 - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь понять, как загрузить файлы конфигурации в Angular 6, у меня в настоящее время есть ConfigureService со следующим кодом для загрузки файла:

configUrl = '../assets/config.json';
config: Config;

load() {
  console.log('loading configuration');
  this.getConfig().subscribe(
    (data: Config) => {
      console.log('Config request success');
      (this.config = data);
      console.log(this.config)
    }
  );
}

private getConfig() {
  return this.http.get<Config>(this.configUrl);
}

Где вызывается load в конструкторе ConfigureService

Я использую этот сервис, чтобы получить строки Url для моих потребительских сервисов API, и он успешно работает (консоль отображается в окне разработчика), но эти службы не успевают использовать свой корректный URL.строки в своих методах OnInit, а другие службы выдают ошибки при попытке извлечь строки из неопределенного объекта конфигурации.

Я попытался прочитать их, указав их в app.module и загрузив их перед запуском, как показано здесь:

https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9

Тем не менее, когда я пытаюсь это сделатьметод, он говорит мне, что файлы не могут быть найдены на сервере, и ошибка в консоли возвращает 404, даже если указанный путь является правильным.

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

Ответы [ 2 ]

0 голосов
/ 31 июля 2019

Это очень хороший вопрос, у нас тоже есть разные серверы (Dev, QC, Stage, Prod), поэтому создание отдельной сборки для каждой среды занимает очень много времени, я никогда не пробовал такой подход к созданию отдельного файла средыДля каждой среды мы решили эту проблему, сохранив URL-адреса и константы Api в файле json.

, поэтому сначала создайте файл json и поместите его в папку assets .

Config.json

{
    "url":{
    "apiUrl": "http://localhost:58357/"
    }
}

Создайте класс модели, который должен иметь свойства с таким же именем, как у Config.json file

Config.ts

 export class Config {
    url: {
        apiUrl: string;
    };
}

Создание службы для импорта Config.json файл

app.config.service.ts

import { Injectable } from '@angular/core';
import { Config } from './models/config';
import { HttpClient, HttpBackend, HttpResponse } from '@angular/common/http';
import { Observable } from '../node_modules/rxjs';
import { map } from 'rxjs/operators';

@Injectable({
providedIn: 'root'
})
export class AppConfig {

static Settings: Config;
private http: HttpClient;
constructor(private httpBackEnd: HttpBackend) {
    this.http = new HttpClient(httpBackEnd);
}
load() {
    const jsonFile = 'assets/config.json';
    return new Promise<void>((resolve, reject) => {
    this.http.get(jsonFile).toPromise().then((response: Config) => {
       AppConfig.Settings = <Config>response;
       resolve();
    }).catch((response: any) => {
       reject(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`);
    });
    });
 }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppComponent } from './app.component';
import { AppConfig } from '../app.config.service';
import { HttpClientModule } from '../../node_modules/@angular/common/http';


export function initConfig(appConfig: AppConfig) {
return () => appConfig.load();
}

@NgModule({
declarations: [
AppComponent
],
  imports: [
  BrowserModule,
  HttpClientModule,
  ],
providers: [
 AppConfig, { provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfig], multi: true },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

импортировать AppConfig в любой файл компонента, где вы хотите использовать ключи, хранящиеся в файле json.

app.component.ts

import { Component } from '@angular/core';
import { AppConfig } from '../app.config.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
 })
 export class AppComponent {
 title = 'ConstantsManagerDemo';
 constructor() {
 const apiUrl = AppConfig.Settings.url.apiUrl;
 alert(apiUrl);
  }
 }

перейти к tsconfig.json файл и добавить

"allowSyntheticDefaultImports" :true,  
under compilerOptions
0 голосов
/ 06 марта 2019

Возможно, вы захотите использовать асинхронные / ожидающие или перенаправленные обещания:


    config: Promise<Config>;

    load() {
      console.log('loading configuration');
      this.config = requestConfig();
    }

    private requestConfig(): Promise<Config> {
       return this.http.get<Config>(this.configUrl).toPromise();
    }

    // do something asynchronously based on the config
    public async doAsynchonously(consumer: (Config => void)){
      const config = await this.config;
      consumer(config);
    }

    // return another promise that someone can react on, or use asynchronously
    // i.e. push handling of asynchronous behavior to the user of the API
    public someSettingFromConfig(): Promise<string> {
       return this.config.then(config => config.somesetting);       
    }

См. Также: http://www.damirscorner.com/blog/posts/20170127-Angular2TutorialWithAsyncAndAwait.html
И: https://labs.encoded.io/2016/12/08/asyncawait-with-angular/

Еще одна вещь, которую вы, возможно, захотитеdo выполняет синхронный запрос, и здесь я выдаю предупреждение: «Синхронные запросы обычно ухудшают производительность!».

    config : Config;

    load() {
      this.config = requestConfig();
    }

    private requestConfig(): Config {
      const request= new XMLHttpRequest();
      request.open('GET', '/assets/config.json', false);
      if (request.overrideMimeType) {
        request.overrideMimeType('application/json');
      }
      request.send();
      if (request.status === 200) {
        return <Config>JSON.parse(config.responseText);
      }
      // log some error
      return undefined;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...