繁体   English   中英

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

[英]How to load a remote config file for a lazy loaded module in Angular

我有一个 Angular (v6) SPA,其中包含许多延迟加载的模块。 目前,我有一个 json 文件,其中包含应用程序的配置,可以通过单独的管理界面进行更改,而无需重建/部署应用程序。 配置文件当前加载在 APP_INITIALIZER 中,它可以很好地确保我在允许应用程序完全引导之前检索配置。

我想将此配置文件拆分为每个模块,在 APP_INITIALIZER 中加载一个通用配置,并且仅在该特定模块延迟加载时才加载其他配置。

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

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

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

在模块初始化期间获取配置(在构造函数中或在诸如forRoot之类的 static 方法中)将不起作用,因为此时尚未解决依赖关系。 因此,例如,您将没有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$;
  }

}

2. 提供ConfigurationService作为可以动态设置CONFIG_URL的模块的一部分:

@NgModule({
  providers: [ConfigService],
  imports: [
    HttpClientModule
  ]
})
export class ConfigModule {
  static buildForConfigUrl(configUrl: string): ModuleWithProviders {
    return {
      ngModule: ConfigModule,
      providers: [
        {
          provide: CONFIG_URL,
          useValue: configUrl
        }
      ]
    };
  }
}

3. 在您的功能模块中导入ConfigModule

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

@NgModule({
  exports: [
    MyComponent
  ],
  declarations: [
    MyComponent
  ],
  imports: [
    ConfigModule.buildForConfigUrl('https://my-url/my-config.json')
  ]
})
export class FeatureModule {
}

4. 在您的组件中使用ConfigService

@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();
  }

}

使用这种方法,您可以很好地解耦关注点:您的功能模块不需要关心配置是如何加载的,但它的组件仍然具有在运行时可用的配置。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM