我在使用[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在工厂实现内动态添加路由。
  • 添加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] }
                ]
            }
        }
    }
    

    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/

    10-12 15:49