如果您能想到一个
,请建议更好的标题我们有一个用Angular 2编写的多模块企业应用程序
为了处理多用户对我们系统的使用,我们对图像等采用了覆盖策略。基本上是字符串到文件位置的映射。要切换哪些资产被覆盖,我们会通过地图将现有地图覆盖到下面的.forAssets()
方法中。此模式取自Angular 2 RouterModule
源代码。
这个问题是当AOT编译我们得到错误
错误:静态解析符号值时出错。不支持函数调用。考虑使用对导出函数的引用替换函数或lambda,解析/Users/--/-/my-module/index.ts中的符号MainModule,解决/ Users / - / - / common-中的符号MainModule模块/ index.ts
@NgModule({
imports: [
AssetsModule.forAssets(),
SomeModule
]
})
export class MainModule{
public ngDoBootstrap(ref: ApplicationRef){
ref.bootstrap(StartupComponent);
}
}
platformBrowser().bootstrapModuleFactory(MainModuleNgFactory);
@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
AssetsModule,
RouterModule.forRoot(SOME_ROUTES, {useHash: true})
],
providers: [
...
],
schemas:[
NO_ERRORS_SCHEMA
],
bootstrap: [StartupComponent]
})
export class SomeModule {}
复制用于覆盖的Angular 2 RouterModule.forChild()
模式。我为AssetsModule
@NgModule({
declarations: [
ImgDirective
],
providers: [
AssetService
]
})
export class AssetsModule{
public static forAssets(...overrides: any[]): ModuleWithProviders{
const providers = [{provide: ASSETS, multi: true, useValue: DefaultAssets}];
providers.concat(overrides.map(override => {
return {provide: ASSETS, multi: true, useValue: override};
}));
return {
ngModule: AssetsModule,
providers: providers
};
}
}
ASSETS
是OpaqueToken
此错误虽然无用,但只会在顶级模块中存在行AssetsModule.forAssets()
时发生。如果我将其注释掉或删除它,编译就会成功。
答案 0 :(得分:3)
模块类中的静态函数只能有1个语句,该语句必须是return
。
https://github.com/angular/angular/blob/master/tools/@angular/tsc-wrapped/src/collector.ts#L54-L72
答案 1 :(得分:1)
您似乎正在传递用于映射回动态替换的Assets
的可能覆盖类型列表。
AoT编译器不允许我们像这样动态地构建提供者列表。我认为在定义提供者时添加任何逻辑的唯一方法是使用工厂
也许您可以重新设计代码以使用确定要使用哪个覆盖的工厂。
//factory function
export function myFactory(override: WhichAssetToUse): any {
if(override.type === 'type1'){
return {a:1};// some override
}
return {b:1};// a different override
}
public static forAssets(whichAsset: WhichAssetToUse):ModuleWithProviders{
providers:[
{provide: WhichAssetToUse, useClass: whichAsset},
{provide: Asset,
useFactory: myFactory,
deps: [WhichAssetToUse]}]
}
WhichAssetToUse
可以是一个抽象类,也可以是你继承并传入forAssets方法的东西。