Angular 角度5-预加载配置文件

Angular 角度5-预加载配置文件,angular,Angular,Angular 5-预加载配置文件以供跨应用程序使用 我正在寻找一个关于如何预加载配置文件以允许跨应用程序使用的答案,以下是答案-最初的实现来自: 应用程序模块.ts import { AppConfigService } from './services/app-config.service'; export function init_app(configService: AppConfigService){ // Load Config service before loading o

Angular 5-预加载配置文件以供跨应用程序使用

我正在寻找一个关于如何预加载配置文件以允许跨应用程序使用的答案,以下是答案-最初的实现来自:

应用程序模块.ts

import { AppConfigService } from './services/app-config.service';
export function init_app(configService: AppConfigService){
  // Load Config service before loading other components / services
  return () => {
    return configService.load();
  };
}

providers: [AppConfigService,
    {
      'provide': APP_INITIALIZER,
      'useFactory': init_app,
      'deps': [AppConfigService],
      'multi': true,
    }
]
import { Injectable } from '@angular/core';
import {HttpClient, HttpResponse} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class AppConfigService {
  config: any;

  constructor(private http: HttpClient) { }

  load(): Promise<any> {
    return this.http.get('path/to/app-config.json')
      .toPromise()
      .then(res => this.config = res)
      .catch(this.handleError);
    }

  private handleError(error: HttpResponse<any> | any) {
    let errMsg: string;
    if (error instanceof HttpResponse) {
      const currentError: any = error;
      const body = currentError.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    return new Promise((resolve) => {
     resolve(errMsg);
    });
  }
}
app config.service.ts

import { AppConfigService } from './services/app-config.service';
export function init_app(configService: AppConfigService){
  // Load Config service before loading other components / services
  return () => {
    return configService.load();
  };
}

providers: [AppConfigService,
    {
      'provide': APP_INITIALIZER,
      'useFactory': init_app,
      'deps': [AppConfigService],
      'multi': true,
    }
]
import { Injectable } from '@angular/core';
import {HttpClient, HttpResponse} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class AppConfigService {
  config: any;

  constructor(private http: HttpClient) { }

  load(): Promise<any> {
    return this.http.get('path/to/app-config.json')
      .toPromise()
      .then(res => this.config = res)
      .catch(this.handleError);
    }

  private handleError(error: HttpResponse<any> | any) {
    let errMsg: string;
    if (error instanceof HttpResponse) {
      const currentError: any = error;
      const body = currentError.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    return new Promise((resolve) => {
     resolve(errMsg);
    });
  }
}

我有一个类似于您的设置,但是,在我的情况下,当调用延迟加载模块时,数据不是持久的。我必须先将它加载到会话存储中,然后才能使用它。当我从服务中检索数据时,“config”变量为null,我从内存中检索它并将其分配给变量,一旦我这样做,它就可用于服务

//
import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { DataService } from './data.service';

@Injectable()
export class ConfigService {

    private config: any = null;
    private env: any = null;

    // -----------------------------------------------------------------------------------
    constructor(private http: HttpClient, private dataService: DataService) { }

    // -----------------------------------------------------------------------------------
    public load(url?: string): Promise<any> {
        const defaultUrl: string = (url === undefined ? 'appConfig.json' : url);
        const headers = new HttpHeaders();
        const options: any = {
            url: defaultUrl,
            headers: headers,
            withCredentials: false,
            responseType: 'json'
        };

        return this.http.get(defaultUrl, options)
                .toPromise()
                .then((data: any) => {
                    this.config = data;
                    this.dataService.Push('ConfigData', this.config);
                })
                .catch(this.handleError);
    }
    // -----------------------------------------------------------------------------------
    // from https://stackoverflow.com/questions/47791578/angular-5-preload-config-file
    // -----------------------------------------------------------------------------------
    private handleError(error: HttpResponse<any> | any) {
        let errMsg: string;
        if (error instanceof HttpResponse) {
            const currentError: any = error;
            const body = currentError.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        return new Promise((resolve) => {
            resolve(errMsg);
        });
    }
    // -----------------------------------------------------------------------------------
    public getConfig(key: any): any {

        if (null == this.config) {
            // pull from storage
            this.config = this.dataService.Get('ConfigData');
        }

        if (this.config && this.config.hasOwnProperty(key)) {
            return this.config[key];
        }

        return null;
    }
    // -----------------------------------------------------------------------------------

}
//
从“@angular/core”导入{Injectable};
从'@angular/common/http'导入{HttpClient,HttpResponse,HttpHeaders};
导入'rxjs/add/operator/map';
导入“rxjs/add/operator/catch”;
从“./data.service”导入{DataService};
@可注射()
导出类配置服务{
私有配置:any=null;
私有环境:any=null;
// -----------------------------------------------------------------------------------
构造函数(私有http:HttpClient,私有dataService:dataService){}
// -----------------------------------------------------------------------------------
公共加载(url?:字符串):承诺{
const defaultUrl:string=(url==未定义?'appConfig.json':url);
const headers=新的HttpHeaders();
常量选项:任意={
url:defaultUrl,
标题:标题,
使用凭据:false,
responseType:'json'
};
返回此.http.get(默认URL,选项)
.toPromise()
。然后((数据:任意)=>{
this.config=数据;
this.dataService.Push('ConfigData',this.config);
})
.接住(这个.把手错误);
}
// -----------------------------------------------------------------------------------
//从https://stackoverflow.com/questions/47791578/angular-5-preload-config-file
// -----------------------------------------------------------------------------------
私有句柄错误(错误:HttpResponse | any){
让errMsg:string;
if(HttpResponse的错误实例){
const currentError:any=错误;
const body=currentError.json();
const err=body.error | | JSON.stringify(body);
errMsg=`${error.status}-${error.statusText | |'''}${err}`;
}否则{
errMsg=error.message?error.message:error.toString();
}
返回新承诺((解决)=>{
解决(errMsg);
});
}
// -----------------------------------------------------------------------------------
公共getConfig(键:any):any{
if(null==this.config){
//从仓库中取出
this.config=this.dataService.Get('ConfigData');
}
if(this.config&&this.config.hasOwnProperty(键)){
返回此.config[key];
}
返回null;
}
// -----------------------------------------------------------------------------------
}
在我的app.module.ts中

//
import { NgModule, ErrorHandler, LOCALE_ID, APP_INITIALIZER, Injector } from '@angular/core';
import { HttpClient, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatToolbarModule } from '@angular/material';
import { Ng2Webstorage } from 'ngx-webstorage';

import {ConfigService, SharedModule } from '@mylib/mylib-angular-library';

// --------------------------------------------------------------------------
export function configServiceFactory(config: ConfigService) {
  return () => {
    return config.load();
  }
}

//  --------------------------------------------------------------------------

@NgModule({
  imports: [
    BrowserModule
    , HttpClientModule
    , BrowserAnimationsModule    
    , Ng2Webstorage
    , SharedModule  // <-- ConfigService provided in this module
    ...
  ],
  declarations: [
   ...
  ],

  providers: [
    { provide: APP_INITIALIZER, useFactory: configServiceFactory, deps: [ConfigService], multi: true }
  ],
  bootstrap: [AppComponent]
})
export class MainModule { }
//
从“@angular/core”导入{NgModule,ErrorHandler,LOCALE_ID,APP_初始化器,Injector};
从'@angular/common/HTTP'导入{HttpClient,HTTP_拦截器,HttpClientModule};
从“@angular/platform browser”导入{BrowserModule};
从“@angular/platform browser/animations”导入{BrowserAnimationsModule};
从“@angular/material”导入{MatToolbarModule};
从“ngx webstorage”导入{Ng2Webstorage};
从“@mylib/mylib角度库”导入{ConfigService,SharedModule};
// --------------------------------------------------------------------------
导出函数configServiceFactory(配置:ConfigService){
return()=>{
返回config.load();
}
}
//  --------------------------------------------------------------------------
@NGD模块({
进口:[
浏览器模块
,HttpClientModule
,浏览动画模块
,Ng2Webstorage

,SharedModule//如果这是一个答案,您应该将其作为问题的答案发布。而不是作为问题发布。或者将其作为博客发布。我会等待配置请求完成,然后相应地设置我的服务(也不是理想的方式…):(MyService应该实现setConfig方法-根据收到的配置数据设置配置)导出函数configServiceFactory(config:ConfigService,myService:myService){return()=>{const config=ConfigService.load();config.then((数据)=>{myService.setConfig(数据);})return config;};}
导出函数configServiceFactory(config:ConfigService,myService:myService){return()=>{const config=configService.load();config.then((数据)=>{myService.setConfig(数据);})返回配置;};}
谢谢Yonatan Ayalon的帮助。问题是,我加载lazy模块时再次注入了服务,这创建了一个新实例。一旦我删除了它,并且只在父模块中注入了服务,它就会按预期工作。