Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular APP_初始值设定项在成功时不延迟引导_Angular - Fatal编程技术网

Angular APP_初始值设定项在成功时不延迟引导

Angular APP_初始值设定项在成功时不延迟引导,angular,Angular,我正在尝试使用APP_初始化器来进行角度延迟增强,直到我能够获取一些环境变量 我已经阅读并遵循了许多教程和堆栈溢出的答案,没有一个与我看到的相匹配 APP_初始值设定项确实有效,因为如果承诺被拒绝,它会阻止页面加载,但如果成功,则不会。相反,控制台日志记录表明依赖于初始化服务的其他服务试图在初始化服务完成之前使用它,您可以想象所有的欢乐,而不是随后加载所有不存在的东西 互联网和文档证明了这一点。这是我的密码: import { Injectable } from '@angular/core';

我正在尝试使用APP_初始化器来进行角度延迟增强,直到我能够获取一些环境变量

我已经阅读并遵循了许多教程和堆栈溢出的答案,没有一个与我看到的相匹配

APP_初始值设定项确实有效,因为如果承诺被拒绝,它会阻止页面加载,但如果成功,则不会。相反,控制台日志记录表明依赖于初始化服务的其他服务试图在初始化服务完成之前使用它,您可以想象所有的欢乐,而不是随后加载所有不存在的东西

互联网和文档证明了这一点。这是我的密码:

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

export interface IAppConfigDetails {
  environment: any;
  apiUrls: Array<string>;
  googleAnalyticsEnabled: boolean;
}

export const appEnvironmentFactory = (appConfig: AppConfigService) => {
  return () => {
    return appConfig.loadEnvironment();
  };
};

@Injectable()
export class AppConfigService {
  private appConfig: IAppConfigDetails = {
    environment: {},
    apiUrls: [],
    googleAnalyticsEnabled: false,
  };

  constructor(private http: HttpClient) { }

  loadEnvironment() {
    console.log('loadEnvironment called');

    const promise = new Promise((resolve, reject) => {
      this.http.get('/assets/environment.json')
        .toPromise()
        .then((data: any ) => {
          // console.log('About to set environment');
          // console.log(data);
          this.appConfig.environment = data['environment'];
          this.appConfig.apiUrls = data['API_URLS'];
          this.appConfig.googleAnalyticsEnabled = data['GOOGLE_ANALYTICS_ENABLED'];
          resolve(this.appConfig);
          // console.log('Environment fetched');
        }).catch((error) => {
          console.error(
            'Environment definition not found.' +
            'If you\'re running this locally, try calling make_environment.sh to generate a new environment file.'
          );
          console.log(error);
          reject(error);
        });
    });

    return promise;
  }

  getConfig(): IAppConfigDetails {
    return this.appConfig;
  }
}
和供应商参考:

  providers: [
    ...
    AppConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: appEnvironmentFactory,
      multi: true,
      deps: [AppConfigService]
    }
    ...
  ]

我终于在《我真的推荐阅读》中找到了一些关于这个问题的线索

总之,APP_INITIALISER不会保证您的配置服务首先完成,特别是如果您将它提供的服务注入到您的子模块中。显然,您可以通过确保您的应用程序模块不依赖于所提供的服务(这会过早地执行其他模块),来绕过这个问题(我还没有对此进行测试)

但是,如果您确实需要在Angular想要使用配置服务之前运行配置服务,那么最好的方法是修改main.ts以延迟Angular引导。 然后,您可以完全依赖配置服务。(感谢您和他们在帖子中的评论)

实践中的一个例子是:

main.ts

function bootstrapFailed(val: any) {
    document.getElementById('bootstrap-fail').style.display = 'block';
    console.error('bootstrap-fail', val);
}

// If the environment is set to boostrap
if ( environment.bootstrapping && environment.bootstrapping.configuration) {
 fetch('assets/configuration.json')
    .then(response => response.json())
    .then(config => {
        if (!config ) {
            bootstrapFailed(config);
            return;
        }

        // Store the response somewhere that your ConfigService can read it.
      (<any>window)['tempConfigStorage'] = config;

        platformBrowserDynamic()
            .bootstrapModule(AppModule)
            .catch(bootstrapFailed);
    })
    .catch(bootstrapFailed);
} else {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(bootstrapFailed);
}
main.ts
函数引导失败(val:any){
document.getElementById('bootstrap-fail')。style.display='block';
控制台错误('bootstrap-fail',val);
}
//如果环境设置为boostrap
if(environment.bootstrapping&&environment.bootstrapping.configuration){
fetch('assets/configuration.json')
.then(response=>response.json())
。然后(配置=>{
如果(!config){
引导失败(配置);
返回;
}
//将响应存储在ConfigService可以读取的位置。
(窗口)['tempConfigStorage']=config;
platformBrowserDynamic()
.bootstrapModule(AppModule)
.捕获(引导失败);
})
.捕获(引导失败);
}否则{
platformBrowserDynamic()
.bootstrapModule(AppModule)
.捕获(引导失败);
}
configuration.service.ts
@可注射()
导出类配置服务{
/*
配置服务保证在角度引导本身之前运行。
*/
公共appConfig:IAppConfigDetails={
环境:{},
APIRLs:[],
googleAnalyticsEnabled:false,
};
构造函数(){
}
initConfig(jsonData:any){
if(jsonData){
this.appConfig.environment=jsonData.environment;
this.appConfig.apirls=jsonData.API_url;
this.appConfig.googleAnalyticsEnabled=jsonData.GOOGLE\u ANALYTICS\u ENABLED;
}
}
getConfig():IAppConfigDetails{
返回this.appConfig;
}
}
导出函数配置工厂(){
const service=new ConfigurationService();
initConfig((窗口)['tempConfigStorage']);
回程服务;
}

您的提供者部分在模块中的外观如何?您能否在问题中包含日志输出?有助于了解事件的顺序events@robert添加请求information@JonathanSeed添加的请求信息提供者部分看起来正常。我用同样的方法。唯一的区别是,在我的应用程序中,我从“AppConfig”服务发出初始数据请求,调用其他服务等。在您的情况下,您从“EnvironmentService”构造函数发出数据请求太早了。一旦收到“environment.json”,我会将其更改为从“AppConfig”服务调用EnvironmentService的“load”方法。
  providers: [
    ...
    AppConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: appEnvironmentFactory,
      multi: true,
      deps: [AppConfigService]
    }
    ...
  ]
main.ts

function bootstrapFailed(val: any) {
    document.getElementById('bootstrap-fail').style.display = 'block';
    console.error('bootstrap-fail', val);
}

// If the environment is set to boostrap
if ( environment.bootstrapping && environment.bootstrapping.configuration) {
 fetch('assets/configuration.json')
    .then(response => response.json())
    .then(config => {
        if (!config ) {
            bootstrapFailed(config);
            return;
        }

        // Store the response somewhere that your ConfigService can read it.
      (<any>window)['tempConfigStorage'] = config;

        platformBrowserDynamic()
            .bootstrapModule(AppModule)
            .catch(bootstrapFailed);
    })
    .catch(bootstrapFailed);
} else {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(bootstrapFailed);
}
configuration.service.ts

@Injectable()
export class ConfigurationService {
  /*
  Configuration service is guaranteed to have run before Angular bootstraps itself.
   */
  public appConfig: IAppConfigDetails = {
    environment: {},
    apiUrls: [],
    googleAnalyticsEnabled: false,
  };

  constructor() {
  }

  initConfig( jsonData: any) {
    if (jsonData) {
      this.appConfig.environment = jsonData.environment;
      this.appConfig.apiUrls = jsonData.API_URLS;
      this.appConfig.googleAnalyticsEnabled = jsonData.GOOGLE_ANALYTICS_ENABLED;
    }
  }

  getConfig(): IAppConfigDetails {
    return this.appConfig;
  }
}

export function configurationFactory() {
  const service = new ConfigurationService();
  service.initConfig((<any>window)['tempConfigStorage']);
  return service;
}