我在使用[email protected]时遇到了AOT构建问题。
错误是:
ERROR in Error during template compile of 'AppModule'
Function calls are not supported in decorators but 'FeatureModule' was called.
feature.module.ts
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot([])
],
declarations: [
...
],
exports: [
...
]
})
export class FeatureModule{
static forRoot(items:any[]): ModuleWithProviders {
const routes:Routes = items.map(t=> {
return { path: t.name, component: t.component };
});
return {
ngModule: FeatureModule,
providers: [
provideRoutes(routes)
]
}
}
}
这可以在非aot版本中成功编译。这似乎仅是AOT构建的问题。
为什么会发生此错误?
最佳答案
好的,我花了一些时间才弄清楚。
TLDR:forRoot
方法必须简单,否则AOT编译器会提示。
为简单起见,我必须:
forRoot
方法中删除分支逻辑和函数调用。 forRoot
方法中。 Router.resetConfig
在工厂实现内动态添加路由。 entryComponents
中。 RouterModule.forChild([])
中的组件,所以将FeatureModule
导入@angular/router
中。 RouterModule.forRoot([])
导入AppModule
,因为它提供了应用程序范围内的Router
服务。 最终解决方案
export const Items = new InjectionToken<any[]>('items');
export function InitMyService(router:Router, items:any[]) {
var routes:Routes = items.map(t=> { return { path: t.name, component: t.component, outlet: 'modal' }});
var r = router.config.concat(routes);
router.resetConfig(r);
return new MyService(router);
}
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([])
],
declarations: [
MyComponent
],
exports: [
MyComponent
],
providers: [
]
})
export class FeatureModule {
static forRoot(items:any[]): ModuleWithProviders {
return {
ngModule: FeatureModule,
providers: [
{ provide: Items, useValue: items},
{ provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: items},
{ provide: MyService, useFactory: InitMyService, deps:[Router, Items] }
]
}
}
}
app.module.ts
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot([]),
FeatureModule.forRoot([{name: 'test', component: TestComponent}])
],
declarations: [ AppComponent, TestComponent ],
bootstrap: [ AppComponent ],
providers: [
],
exports: [AppComponent]
})
export class AppModule {
}
解决此问题的关键是认识到
RouterModule.forChild()
不注册任何路由器服务。这是有意的,因此任何模块都可以导入RouterModule并利用其组件,而无需实际注册任何服务。在AppModule级别,我仍然需要通过将Router
导入AppModule将RouterModule.forRoot()
服务注册为单例。关于angular - 当静态forRoot有参数时,AOT构建期间FeatureModule失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47686638/