错误TypeError:无法读取角度4中未定义的属性“createComponent”

时间:2018-03-09 15:57:38

标签: angular typescript

我是角度4的新手,我正在使用“动态组件加载”来制作项目,但是有一个createComponent用于加载组件的问题。

component 在上图中有四个部分。

  1. 顶部(headerComponent)
  2. 活动部分(EventsComponent) 注意: - 事件部分有两个动态组件(2.1,2.2)
    2.1。特定事件的事件详细信息部分(EventDetailComponent) 2.2。用户表单部分(UserFormComponent)
  3.   

    当点击顶部标题中的“事件”标签时,我们正在点击事件api和   在左侧栏中显示事件,然后点击事件详细信息api load   “2.1活动详情”屏幕。当点击show user然后再次加载   “2.2用户表格”动态表格。

    问题: - 当点击特定事件的事件详细信息的api并且api现在正在等待状态然后用户点击“创建事件”选项卡然后它将创建事件屏幕并再次用户单击事件选项卡然后显示事件详细信息的createComponent错误。也点击添加用户按钮然后再次显示相同的错误。

    代码: -

    ngAfterViewInit() {
      this.getEventList('init');
    }
    
    public getEventList(listsource) {
      this.appService.getJsonRequest(AppSettings.EVENT_LIST).subscribe(result => {
        if (result.status === 200  && result.events) {
          this.events = result.events;
          this.publicEvents = result.events;
          this.events[0].selected = true;
          this.selectedEVentInfo = this.events[0];
          this.noImgFlag = true;
          this.eventDetailFlag = false;
            this.eventDetailInfo(listsource); 
        } else {
          this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
        }
        // this.loaderFlag = false;
      }, err => {
        this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
        this.loaderFlag = false;
        this.snackBar.open(err, AppSettings.CLOSE, {
          duration: AppSettings.DURATION,
        });
      });
    }
    
    
      eventDetailInfo  (event, source: String = null) { // event detail
       console.log('### Get event detail information');
       if (this.eventDetailFlag === false) {
        if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined) { // testing needed
          console.log('clear');
          this.ed.clear();
        }
    
            let edCompFactory: ComponentFactory<any>;
            edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
            const componentRef = this.ed.createComponent(edCompFactory);
            (<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
          }
       }
     }
    

    添加用户代码: -

    expandAddEventMember(fullWidth) {
    if (this.fullWidth === true && fullWidth === true) {
      console.log('Before');
        if (this.am !== undefined) {
          this.am.clear();
        }
      // setTimeout(() => {
        let amCompFactory: ComponentFactory<any>;
        amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
        const componentRef = this.am.createComponent(amCompFactory);
        (<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
        this.fullWidth = false;
      // }, 100);
      }
    }
    

    错误: - enter image description here

    这是我的entryComponent

      entryComponents: [
    AppComponent,
    ForgotModalComponent,
    EventDetailsModalComponent,
    AddManagerModalComponent,
    AddAdminModalComponent,
    CopyLinkModalComponent,
    OrderSummaryModalComponent,
    EventPreviewModalComponent,
    PaidMemberModalComponent,
    SendMessageModalComponent,
    TicketInfoModalComponent,
    AddPaidMemberModalComponent,
    MessageModalComponent,
    TicketCheckInDetailModalComponent,
    SaleItemModalComponent,
    SaleItemListModalComponent,
    ApmComponent,
    PmComponent,
    AsmComponent,
    SlmComponent,
    TiComponent,
    EdComponent,
    AmComponent,
    SihComponent,
    ImageModalComponent,
    GoogleMapModalComponent
    ]
    

1 个答案:

答案 0 :(得分:1)

您只需要确保在创建组件之前实例化amem。我认为它们可以是未定义的,因为在您的代码中,您已经检查amem在某个阶段(在调用if(this.am !== undefined)之前)实例化clear,但不会调用createComponent。只是您需要在createComponent

中包含我们的if代码
  eventDetailInfo(event, source: String = null)
  { // event detail
    console.log('### Get event detail information');
    if (this.eventDetailFlag === false)
    {
      if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined)
      { // testing needed
        console.log('clear');
        this.ed.clear();
        /*}  <======= Remove this bracket*/

        let edCompFactory: ComponentFactory<any>;
        edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
        const componentRef = this.ed.createComponent(edCompFactory);
        (<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
      }/* <========== Add it here */

    }
  }

addUser

相同
  expandAddEventMember(fullWidth)
  {
    if (this.fullWidth === true && fullWidth === true)
    {
      console.log('Before');
      if (this.am !== undefined)
      {
        this.am.clear();
        /* } <=== Remove this bracket **/
        let amCompFactory: ComponentFactory<any>;
        amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
        const componentRef = this.am.createComponent(amCompFactory);
        (<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
        this.fullWidth = false;
      } /** <==== Add it here */

    }
  }

修改:关于您对其进行规范化的评论,您应该打开另一个问题,因为它是一个完全不同的问题。下面的代码可能不起作用(未经过测试),但可以让您了解一种方法

@Injectable()
export class CompFactoryHelper
{
  constructor(private resolver: ComponentFactoryResolver)
  {

  }

public createAndAddComponent(containerRef: ViewContainerRef, eventInfo : any, type: any)
   {
        containerRef.clear();
        let compFactory = this.resolver.resolveComponentFactory(type);
        const componentRef = containerRef.createComponent(compFactory);
        (componentRef.instance as any).event = eventInfo;
   }
}

并在您的组件中

 expandAddEventMember(fullWidth)
  {
    if (this.fullWidth === true && fullWidth === true)
    {
      console.log('Before');
      if (this.am !== undefined)
      {
        this.compFactoryHelper.createAndAddComponent(this.am,  this.selectedEVentInfo, AmComponent);

      } 

    }
  }