我的应用程序不是SPA,但我在页面的某些部分使用Angular 2。我创建了多个根模块,我用可注入的提供程序引导,其中包含来自外部世界的信息:
根模块1:
let serviceOne = new ServiceOne("SuperImportantInfoFromSomewhere");
let providers: any = [{ provide: ServiceOne, useValue: serviceOne }];
platformBrowserDynamic(MyFirstRootModule, providers);
根模块2,位于页面底部的某个位置:
let serviceTwo = new ServiceTwo(42);
let providers: any = [{ provide: ServiceTwo, useValue: serviceTwo }];
platformBrowserDynamic(MySecondRootModule, providers);
可悲的是,这不起作用。当我希望ServiceTwo
注入组件时,它会失败。它只适用于我在第一个引导程序中提供这两种服务(在本例中为MyFirstRootModule
)。它必须与我不完全理解的新DI系统有关。
因为我在CMS中工作,所以我不知道第一个引导程序中的所有提供者;这两个模块甚至都不认识。
有没有办法完全分离这两个模块,或者在第一个根模块被引导后以某种方式向DI系统提供第二个服务?
答案 0 :(得分:0)
我想出了一个非常肮脏的解决方法。在引导模块之前,我使用Reflect API将提供程序直接添加到类的注释中:
import "reflect-metadata";
import { MySecondRootModule } from "MySecondRootModule";
import { ServiceTwo } from "ServiceTwo";
export class MySecondRootApplication
{
constructor()
{
let serviceTwo = new ServiceTwo(42);
let annotations: Array<any> = (Reflect as any).getMetadata("annotations", MySecondRootModule);
if (annotations[0].providers != undefined)
{
annotations[0].providers.push({ provide: ServiceTwo, useValue: serviceTwo });
}
else
{
annotations[0].providers = [{ provide: ServiceTwo, useValue: serviceTwo }];
}
(Reflect as any).defineMetadata("annotations", annotations, type);
// Perform what ever else needs to be done
platformBrowserDynamic(MySecondRootModule);
}
}
我知道,这很糟糕。但它的确有效。顺便说一下:使用此方法还可以更改templateUrl,例如,如果要使用ASP.NET MVC局部视图结果。