0

Angular 2+ 以下列方式注册提供者:

// @NgModule decorator with its metadata
@NgModule({
  declarations: [...],
  imports: [...],
  providers: [<PROVIDERS GO HERE>],
  bootstrap: [...]
})
export class AppModule { }

我想与此声明站点分开注册应用程序范围的提供程序。

具体来说,我正在使用 NSwag 为我的整个 Web API 生成服务客户端,并且我希望将它们全部动态添加为提供程序。但是,我不确定如何做到这一点,因为@NgModule它是应用于此类的属性AppModule

这可能吗?

4

1 回答 1

1

任何 DI 提供程序都需要在编译时包含在模块中。

由于 Angular 依赖注入适用于 Typescript 类型符号/标记,因此在编译后没有 Javascript 功能可以完成相同的任务。

您可以做的是编译时动态添加提供程序,如下所示:

import { Load, SomeToken } from '../someplace';


@NgModule({
  declarations: [...],
  imports: [...],
  providers: [
    {
      provide: SomeToken,
      useValue: Load(someVariable)
  ],
  bootstrap: [...]
})
export class AppModule { }

然后在别处实现 Load 函数和令牌:

export const SomeToken = new OpaqueToken<any>('SomeToken');

export const Load = (someVariable) => {
  // logic to return an @Injectable here. Variable provided could be something like an environment variable, but it has to be exported and static
}

这种方法当然有需要在编译时知道的限制。另一种方法是全局导入整个应用程序所需的所有提供程序,无论情况如何,然后延迟加载为该情况注入了适当提供程序的组件(Angular 不会初始化提供程序,直到使用它的组件被初始化),或者创建一个本身能够执行逻辑而不管动态标准的提供程序。一个想法是创建另一个服务,该服务利用该服务并根据该动态标准解决问题(即,您可以GetLoginInfo在第一个服务上调用一个方法,而第二个服务将能够为该方法解析正确的 API 调用.)

如果它只是您需要的 API 信息(即 URL),那么您可以通过从 config.json 文件或 API 调用中获取 URL 信息来实现上述目的,并将这些值注入到服务中,以便调用和令牌保持不变,但使用不同的值。有关如何完成此操作的更多信息,请参见此处。

于 2018-02-06T16:29:23.650 回答