【问题标题】:Angular Cannot read property 'create' of undefinedAngular 无法读取未定义的属性“创建”
【发布时间】:2018-09-28 07:35:44
【问题描述】:

我正在使用Angular 6,我想根据instructions实现组件的动态添加,但是我得到一个错误:“无法读取未定义的属性'create'。”

component.html

<mat-card>
  <mat-card-header>
    <mat-card-title>...</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <ng-template answerHost></ng-template>
  </mat-card-content>
</mat-card>

component.ts

@ViewChild(AnswerHostDirective) answerHost: AnswerHostDirective;
private stepAnswerType1: ComponentFactory<StepAnswerType1Component>;
private stepAnswerType2: ComponentFactory<StepAnswerType2Component>;
private stepAnswerType3: ComponentFactory<StepAnswerType3Component>;

/* ... */

changeStep(id: number) {
    let viewContainerRef = this.answerHost.viewContainerRef;

    let componentRef;
    if (this.step.type == 1) {
      componentRef = viewContainerRef.createComponent(this.stepAnswerType1);
    }
    if (this.step.type == 2) {
      componentRef = viewContainerRef.createComponent(this.stepAnswerType2);
    }
    if (this.step.type == 3) {
      componentRef = viewContainerRef.createComponent(this.stepAnswerType3);
    }
}

指令

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[answerHost]'
})
export class AnswerHostDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

我尝试将指令替换为对组件 ID 的引用,但我得到了同样的错误。 component.html

<mat-card>
  <mat-card-header>
    <mat-card-title>...</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <ng-template #answerContainer></ng-template>
  </mat-card-content>
</mat-card>

component.ts

@ViewChild('answerContainer', { read: ViewContainerRef }) answerContainer: ViewContainerRef;
private stepAnswerType1: ComponentFactory<StepAnswerType1Component>;
private stepAnswerType2: ComponentFactory<StepAnswerType2Component>;
private stepAnswerType3: ComponentFactory<StepAnswerType3Component>;

/* ... */

changeStep(id: number) {
    if (this.step.type == 1) {
      componentRef = this.answerContainer.createComponent(this.stepAnswerType1);
    }
    if (this.step.type == 2) {
      componentRef = this.answerContainer.createComponent(this.stepAnswerType2);
    }
    if (this.step.type == 3) {
      componentRef = this.answerContainer.createComponent(this.stepAnswerType3);
    }
}

可能是什么问题?

已修复 我更新了部分代码。 组件.ts

import { StepAnswerType1Component } from './step-answer-type1/step-answer-type1.component';
import { StepAnswerType2Component } from './step-answer-type2/step-answer-type2.component';
import { StepAnswerType3Component } from './step-answer-type3/step-answer-type3.component';

/* some code */

@ViewChild('answerContainer', { read: ViewContainerRef }) answerContainer: ViewContainerRef;

/* some code */

changeStep(id: number) {
    let componentRef, componentFactory;
    if (this.step.type == 1) {
      componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType1Component);
    }
    if (this.step.type == 2) {
      componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType2Component);
    }
    if (this.step.type == 3) {
      componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType3Component);
    }
    componentRef = viewContainerRef.createComponent(componentFactory);
 }

【问题讨论】:

  • 尝试使用 ng-container 更改 ng-template
  • 同样的错误。

标签: angular typescript


【解决方案1】:

确保您在 'ngAfterViewInit()' 中调用此方法 'changeStep'。

【讨论】:

  • 我尝试从 ngOninit 和 ngAfterViewInit 调用方法 changeStep。结果是一样的。
  • 创建了一个堆栈溢出并且它工作正常。 stackblitz.com/edit/angular-material-with-angular-v5-eefxju
  • 请注意,我正在使用 createComponent 和 Angular 6。您的示例是 CreativeEmbededViev 和 Angular 2。
  • 我能够访问 ViewContainerRef 实例类可用的所有公共方法。即 clear()、createEmbeddedView()。 createComponent() 也可以工作。
  • 我已经用 createComponent 方法更新了 stackblitz
猜你喜欢
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 2020-10-15
  • 2020-05-28
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多