Cannot read property 'viewContainerRef' of undefined

我的未来我决定 提交于 2020-08-24 05:10:18

问题


I am trying to display a dynamic component similar (not exact) to the example in angular docs.

I have a dynamic directive with viewContainerRef

@Directive({
   selector: '[dynamicComponent]'
})
export class DynamicComponentDirective {
   constructor(public viewContainerRef: ViewContainerRef) { }
}

Excerpt from component code

@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);
}

Finally added <ng-template dynamicComponent></ng-template> in template


回答1:


You can take this approach: don't create directive, instead give an Id to ng-template

<ng-template #dynamicComponent></ng-template>

use @ViewChild decorator inside your component class

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

ngAfterViewInit() {
    const factory = this.componentFactoryResolver.resolveComponentFactory(component);
    const ref = this.myRef.createComponent(factory);
    ref.changeDetectorRef.detectChanges();
}



回答2:


I had the same problem. You have to add the directive into the AppModule:

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



回答3:


In Angular 8 my fix was:

@ViewChild('dynamicComponent', {static: true, read: ViewContainerRef}) container: ViewContainerRef;



回答4:


I ran into this problem as well and the reason was that the location which I wanted to load my component dynamicly into was inside an ng-if that was hidden initially.

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

@ViewChild(InputHostDirective, { static: true }) inputHost: InputHostDirective;

Moving the ng-template to outside the ng-if solved the problem.




回答5:


Noted that I face the same problem if directive selector (dynamicComponent in this case) is at :

  1. first element of the component

  2. parent element with *ngIf condition

Hence, I avoid it by put it inside at non-root tag in the component html & load component to viewContainerRef only when the condition match.




回答6:


The problem might also be that the selector of the viewRef (dynamicComponent in this example) does not match the one specified in the template of the component which uses the componentFactoryResolver.




回答7:


You see this error when the directive does not construct. You can set a breakpoint on the directive's constructor and check if the breakpoint ever hits. If not, that means that you are not loading the directive correctly. Then you can check that your component that is loading the directive it is properly adding the directive into the template.



来源:https://stackoverflow.com/questions/48330760/cannot-read-property-viewcontainerref-of-undefined

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!