Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.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中为延迟加载的模块加载远程配置文件_Angular_Config - Fatal编程技术网

如何在Angular中为延迟加载的模块加载远程配置文件

如何在Angular中为延迟加载的模块加载远程配置文件,angular,config,Angular,Config,我有一个角度(v6)SPA,有许多延迟加载的模块。目前,我有一个json文件,用于保存应用程序的配置,可以通过单独的管理界面进行更改,而无需重新构建/部署应用程序。配置文件当前加载在APP_初始值设定项中,该初始值设定项可以很好地确保在允许应用程序完全引导之前检索配置 我想将此配置文件按模块划分,在APP_初始值设定项中加载一个常规配置,并且仅在该特定模块延迟加载时加载其他配置 是否有一种公认的或最佳实践的方法来做到这一点?我似乎找不到任何在角文件或一般在网上。一种方法可能是在模块构造函数中获取

我有一个角度(v6)SPA,有许多延迟加载的模块。目前,我有一个json文件,用于保存应用程序的配置,可以通过单独的管理界面进行更改,而无需重新构建/部署应用程序。配置文件当前加载在APP_初始值设定项中,该初始值设定项可以很好地确保在允许应用程序完全引导之前检索配置

我想将此配置文件按模块划分,在APP_初始值设定项中加载一个常规配置,并且仅在该特定模块延迟加载时加载其他配置

是否有一种公认的或最佳实践的方法来做到这一点?我似乎找不到任何在角文件或一般在网上。一种方法可能是在模块构造函数中获取配置,但就我所见,在检索并存储此配置文件之前,我无法阻止模块继续加载和设置其所有组件等

如果我在延迟加载模块的根路由上设置路由解析器,那么路由解析器是否可以达到这个目的?例如,不返回任何数据,我可以将一些“ConfigService”注入解析器,解析器将检索并存储相应的配置文件,然后让解析器解析


然后,此模块中的组件可以注入相同的ConfigService,以访问检索到的任何配置点。

在模块初始化期间获取配置(在构造函数中或在静态方法中,如
forRoot
)将不起作用,因为依赖关系在该点尚未解决。例如,您将无法使用
HttpClient
获取数据

可行的方法是什么:

1。提供一个
ConfigurationService
,该服务获取注入的配置文件的URL

@Injectable()
export class ConfigService {

  private config$ = new BehaviorSubject<any | null>(null);
  private loadedConfig = false;

  constructor(@Inject(CONFIG_URL) private configUrl: string,
              private httpClient: HttpClient) {
    this.getConfig();
  }

  getConfig(): Observable<any> {
    if (!this.loadedConfig) {
      this.loadedConfig = true;
      this.httpClient.get(this.configUrl).subscribe(this.config$);
    }
    return this.config$;
  }

}
3。在功能模块中导入
ConfigModule

现在,当您有一个功能模块应该有自己的配置可用时,只需使用
buildForConfigUrl
导入
ConfigModule

@NgModule({
  exports: [
    MyComponent
  ],
  declarations: [
    MyComponent
  ],
  imports: [
    ConfigModule.buildForConfigUrl('https://my-url/my-config.json')
  ]
})
export class FeatureModule {
}
4。在组件中使用
ConfigService

@NgModule({
  providers: [ConfigService],
  imports: [
    HttpClientModule
  ]
})
export class ConfigModule {
  static buildForConfigUrl(configUrl: string): ModuleWithProviders {
    return {
      ngModule: ConfigModule,
      providers: [
        {
          provide: CONFIG_URL,
          useValue: configUrl
        }
      ]
    };
  }
}
@Component({
  selector: 'my-component',
  template: 'I am your new component. My config is: {{ config$ | async | json }}'
})
export class MyComponent implements OnInit{

  config$: Observable<any>;

  constructor(private configService: ConfigService) {
  }

  ngOnInit(): void {
    this.config$ = this.configService.getConfig();
  }

}
@组件({
选择器:“我的组件”,
模板:“我是您的新组件。我的配置是:{{config$| async | json}”
})
导出类MyComponent实现OnInit{
配置$:可观察;
构造函数(专用configService:configService){
}
ngOnInit():void{
this.config$=this.configService.getConfig();
}
}
通过这种方法,您可以很好地将关注点解耦:您的功能模块不需要关心配置是如何加载的,但其组件在运行时仍然具有可用的配置


如果您想更进一步,甚至可以从功能模块中删除配置URL的定义,并将其集中移动到
AppModule

谢谢,我将尝试一下。不过有一个问题。MyComponent中对configService.getConfig()的调用是否触发了HTTP请求?这难道不意味着只有当某个组件试图访问某个组件时才会发出请求,并且可能每次另一个组件想要访问某个组件时都会发出请求吗?我希望当配置服务使用其URL实例化时,请求被发出一次。我相应地更新了我的答案,使每个模块只加载配置一次,然后将其缓存在ConfigService中的BehaviorSubject中