我正在使用Angular@5.1.0遇到AOT构建问题.
错误是:
ERROR in Error during template compile of 'AppModule'
Function calls are not supported in decorators but 'FeatureModule' was called.
Run Code Online (Sandbox Code Playgroud)
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)
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
这在非aot构建中成功编译.这似乎只是AOT构建的一个问题.
为什么会发生这种错误?
好的,我花了一些时间才弄清楚。TLDR:该forRoot方法必须简单,否则AOT编译器会抱怨。
为简单起见,我必须:
从forRoot方法中删除分支逻辑和函数调用。
实现逻辑以将项目映射到路由到工厂提供程序中,而不是将其内联到forRoot方法中。
用于Router.resetConfig在工厂实现内动态添加路由。
添加ANALYZE_FOR_ENTRY_COMPONENTS提供程序,以便将传入的任何组件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] }
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 {
}
Run Code Online (Sandbox Code Playgroud)
The key to solving this was the realization that RouterModule.forChild() does not register any router services. This is intentional so that any module can import the RouterModule and take advantage of its components, without actually registering any services. At the AppModule level, I still needed to register the Router service as a singleton by importing RouterModule.forRoot() into AppModule.
| 归档时间: |
|
| 查看次数: |
1640 次 |
| 最近记录: |