使用* ngComponentOutlet ngModuleFactory在生产中效果不佳

时间:2018-03-21 15:31:26

标签: angular

在Angular 4上创建动态组件时,我使用了ngComponentOutlet。我的代码在开发中很好用,但在生产中却没有。

@Component({
  selector: 'dynamic-detail',
  template: `<ng-container *ngComponentOutlet="dynamicComponent; ngModuleFactory: dynamicModule;"></ng-container>`,
})
export class DynamicDetail implements OnInit {
  ...
  public ngOnInit(): void {
    var template = '<a custom-directive> </a>';

    this.dynamicComponent = this.createNewComponent(template);
    this.dynamicModule = this.compiler.compileModuleSync( this.createComponentModule( this.dynamicComponent ) );
  }

  protected createNewComponent(tmpl: string) {
    @Component({ selector: 'dynamic-component', template: tmpl })
    class CustomDynamicComponent{ constructor() {} };
    return CustomDynamicComponent;
  }

  protected createComponentModule(componentType: any) {
    @NgModule({
        imports: [  WidgetsModule ],
        entryComponents: [ componentType ],
        declarations: [ componentType ],
    })
    class RuntimeComponentModule { }
    return RuntimeComponentModule;
  }
} 

小部件模块包含customDirective的导出和声明。 当我运行代码时,它工作。但如果我用生产标志构建它会给出错误:

vendor.js:1 ERROR Error: No component factory found for l. Did you add it to @NgModule.entryComponents?

at B (vendor.js:1)
at t.resolveComponentFactory (vendor.js:1)
at t.ngOnChanges (vendor.js:1)
at vendor.js:1
at vendor.js:1
at on (vendor.js:1)
at Sn (vendor.js:1)
at Object.updateDirectives (main.js:1)
at Object.updateDirectives (vendor.js:1)
at rn (vendor.js:1)
(anonymous) @ vendor.js:1
vendor.js:1 ERROR Error: Uncaught (in promise): Error: Unexpected value 'n' 
imported by the module 'l'. Please add a @NgModule annotation.
Error: Unexpected value 'n' imported by the module 'l'. Please add a @NgModule annotation.
at l (vendor.js:1)
at vendor.js:1
at Array.forEach (<anonymous>)
at t.getNgModuleMetadata (vendor.js:1)
at t._loadModules (vendor.js:1)
at t._compileModuleAndComponents (vendor.js:1)
at t.compileModuleSync (vendor.js:1)
at t.compileModuleSync (vendor.js:1)
at n.refreshContent (main.js:1)
at n.ngOnChanges (main.js:1)
at l (vendor.js:1)
at vendor.js:1
at Array.forEach (<anonymous>)
at t.getNgModuleMetadata (vendor.js:1)
at t._loadModules (vendor.js:1)
at t._compileModuleAndComponents (vendor.js:1)
at t.compileModuleSync (vendor.js:1)
at t.compileModuleSync (vendor.js:1)
at n.refreshContent (main.js:1)
at n.ngOnChanges (main.js:1)
at c (polyfills.js:3)
at c (polyfills.js:3)
at polyfills.js:3
at t.invokeTask (polyfills.js:3)
at Object.onInvokeTask (vendor.js:1)
at t.invokeTask (polyfills.js:3)
at r.runTask (polyfills.js:3)
at o (polyfills.js:3)

1 个答案:

答案 0 :(得分:0)

我认为这里的问题是当你构建--prod模式时,类名被混淆了(因此找不到错误'n')

您的CustomDirective的名称被混淆为n。编译器尝试创建此类型“n”,但无法找到定义。

当我尝试通过组件工厂解析器创建组件时,我遇到了类似的问题。我的解决方案是在我的组件中创建一个与类名对应的静态变量。

当我动态创建组件时,我在可用的工厂中搜索了这个名称。

var factories = Array.from(this.componentFactoryResolver['_factories'].keys());
      return <Type<any>>factories.find((x: any) => x.componentName === name);

我不确定你的createNewComponent()是做什么的,但我想应该在那里完成。

可以在此处找到详细阐述解决方案的好答案:.insertAdjacentHTML()