无法读取未定义的属性'viewContainerRef'

mpe*_*rle 9 angular-directive angular-components angular

我试图在角度文档中显示一个类似(不完全)的动态组件.

我有一个带有viewContainerRef的动态指令

@Directive({
   selector: '[dynamicComponent]'
})
export class DynamicComponentDirective {
   constructor(public viewContainerRef: ViewContainerRef) { }
}
Run Code Online (Sandbox Code Playgroud)

摘自组件代码

@ViewChild(DynamicComponentDirective) adHost: DynamicComponentDirective;
..
ngAfterViewInit() {
let componentFactory = null;
                console.log(component);
                componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
                // this.adHost.viewContainerRef.clear();
                const viewContainerRef = this.adHost.viewContainerRef;
                viewContainerRef.createComponent(componentFactory);
}
Run Code Online (Sandbox Code Playgroud)

最后<ng-template dynamicComponent></ng-template>在模板中添加

Roh*_*rma 15

你可以采用这种方法:不要创建指令,而是给出一个Id ng-template

<ng-template #dynamicComponent></ng-template>
Run Code Online (Sandbox Code Playgroud)

@ViewChild在组件类中使用装饰器

@ViewChild('dynamicComponent', { read: ViewContainerRef }) myRef

ngAfterViewInit() {
    const factory = this.componentFactoryResolver.resolveComponentFactory(component);
    const ref = this.myRef.createComponent(factory);
    ref.changeDetectorRef.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)

  • 这行得通,所以谢谢,但是我很好奇为什么行得通。我的指令选择器是正确的,但是由于任何原因都找不到。当我切换到ID选择器时,它选择了它。 (2认同)

小智 14

在 Angular 8 中,我的修复是:

@ViewChild('dynamicComponent', {static: true, read: ViewContainerRef}) container: ViewContainerRef;
Run Code Online (Sandbox Code Playgroud)


小智 11

我有同样的问题。您必须将指令添加到AppModule中:

 @NgModule({
  declarations: [
    AppComponent,
    ...,
    YourDirective,
  ],
  imports: [
   ...
  ],
  providers: [...],
  bootstrap: [AppComponent],
  entryComponents: [components to inject if required]
})
Run Code Online (Sandbox Code Playgroud)

  • 解决了我的问题,但在 Angular 教程中没有提到。谢谢 (2认同)

Ash*_*old 6

我也遇到了这个问题,原因是我想动态加载组件的位置在最初隐藏的 ng-if 中。

<div *ngIf="items">
   <ng-template appInputHost></ng-template>
</div>

@ViewChild(InputHostDirective, { static: true }) inputHost: InputHostDirective;
Run Code Online (Sandbox Code Playgroud)

将 ng-template 移到 ng-if 之外解决了问题。