【问题标题】:No component factory found for undefined. Did you add it to @NgModule.entryComponents未找到未定义的组件工厂。您是否将其添加到 @NgModule.entryComponents
【发布时间】:2019-01-30 02:11:05
【问题描述】:

我创建了一个 Angular 6 组件库。 该库基于 PrimeNG 组件。 库中的组件之一是表格组件(基于 PrimeNG 表格)

为了允许库的用户在表格的单元格中添加动态模板,我(在库中)创建了一个名为“VarintComponent”的组件,该组件有两个输入:

1) 访客组件:字符串

2) 访客组件数据:任意

表的用户,可以声明一列包含 VariantComponent,并将组件的名称传递给 GuestComponent 输入。 在运行时,VariantComponent 使用componentFactoryResolverviewContainerRef 动态创建和加载组件。

import { Component, OnInit, Input, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { Type } from '@angular/core';
import { VariantComponentDirective } from './variant-component.directive';

@Component({
  selector: 'o-variant',
  template: `
        <ng-template variantComponent></ng-template>
        `
})
export class VariantComponent implements OnInit {
  @Input() GuestComponent: String;
  @Input() GeustComponentData: any;

  @ViewChild(VariantComponentDirective) variantHost: VariantComponentDirective;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  ngOnInit() {
    this.loadComponent();
  }

  loadComponent() {
    const viewContainerRef = this.variantHost.viewContainerRef;
    viewContainerRef.clear();

    const factories = Array.from(this.componentFactoryResolver['_factories'].keys());
    const factoryClass = <Type<any>>factories.find((x: any) => x.name === (this.GuestComponent));
    const factory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
    const compRef = viewContainerRef.createComponent(factory);

    (<any>compRef.instance).data = this.GeustComponentData;
  }

}

来宾组件需要实现简单的接口来托管在 VariantComponent 中。

客户组件也被声明为它们模块的“entryComponents”。

在不同的项目中使用表格时,我可以看到一切正常,Gust 组件正确托管在 VarintComponent 中并显示在表格中。

问题是在构建生产包时(使用ng build --prod)我得到:

main.11fb9744a37aae5b78f8.js:1 ERROR Error: No component factory found for undefined. Did you add it to @NgModule.entryComponents?

无论来宾组件位于库还是客户端项目中,我都会收到此错误。

如果我使用 ng build --build-optimizer=false 构建代码,代码运行良好

【问题讨论】:

    标签: angular angular-cli-v6 angular-library


    【解决方案1】:

    发现问题。 问题出在以下行:

    const factoryClass = <Type<any>>factories.find((x: any) => x.name === (this.GuestComponent));
    

    当使用--prod 打包时,包会变丑并且类名会更改,因此我们无法按名称进行比较。 所以我们需要通过引用传递组件。 以下代码效果很好:

    import { Component, OnInit, Input, ViewChild, ComponentFactoryResolver } from '@angular/core';
    import { VariantComponentDirective } from './variant-component.directive';
    
    
    @Component({
      selector: 'o-variant',
      template: `
            <ng-template variantComponent></ng-template>
            `
    })
    export class VariantComponent implements OnInit {
      @Input() GuestComponent: any;
      @Input() GeustComponentData: any;
    
      @ViewChild(VariantComponentDirective) variantHost: VariantComponentDirective;
    
      constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
    
      ngOnInit() {
        this.loadComponent();
      }
    
      loadComponent() {
        const viewContainerRef = this.variantHost.viewContainerRef;
        viewContainerRef.clear();
        const factory = this.componentFactoryResolver.resolveComponentFactory(this.GuestComponent);
        const compRef = viewContainerRef.createComponent(factory);
        (<any>compRef.instance).data = this.GeustComponentData;
      }
    
    }
    

    【讨论】:

    • 这可以创建循环引用
    猜你喜欢
    • 2018-04-09
    • 2019-11-06
    • 2018-08-07
    • 1970-01-01
    • 2019-04-10
    • 2019-07-25
    • 2018-01-06
    • 2019-11-05
    相关资源
    最近更新 更多