Angular 2+ 通过以下方式注册提供者:
// @NgModule decorator with its metadata
@NgModule({
declarations: [...],
imports: [...],
providers: [<PROVIDERS GO HERE>],
bootstrap: [...]
})
export class AppModule { }
我想从该声明站点单独注册应用程序范围的提供商。
具体来说,我正在使用 NSwag 为整个 Web API 生成服务客户端,并且我想将它们全部动态添加为提供者。但是,我不确定如何执行此操作,因为 @NgModule
是应用于此 AppModule
类的属性。
这可能吗?
最佳答案
任何 DI 提供程序都需要在编译时包含在模块中。
由于 Angular 依赖注入(inject)使用 Typescript 类型符号/标记,因此编译后没有 Javascript 功能可以完成相同的任务。
您可以做的是在编译时动态添加提供程序,如下所示:
import { Load, SomeToken } from '../someplace';
@NgModule({
declarations: [...],
imports: [...],
providers: [
{
provide: SomeToken,
useValue: Load(someVariable)
],
bootstrap: [...]
})
export class AppModule { }
然后在其他地方实现 Load 函数和 token :
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
}
这种方法当然有需要在编译时知道的限制。另一种方法是全局导入整个应用程序所需的所有提供程序,无论情况如何,然后延迟加载为该情况注入(inject)适当提供程序的组件(Angular 不会初始化提供程序,直到使用它的组件被初始化),或者创建一个提供者,无论动态标准如何,其本身都能够执行逻辑。一个想法是创建另一个服务,利用该服务并根据该动态条件解决问题(即,您可以在第一个服务上有一个名为GetLoginInfo
的方法,并且第二个服务将能够解析该方法的正确 API 调用。)
如果您只是需要 API 信息(即 URL),那么您可以通过从 config.json 文件或 API 调用中获取 URL 信息来实现上述目的,并将这些值注入(inject)到服务中,以便保留调用和 token 相同但使用不同的值。请参阅here了解有关如何实现这一目标的更多信息。
关于javascript - 在 AppModule 声明后添加提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48647311/