web-dev-qa-db-fra.com

Impossible de lire la propriété 'viewContainerRef' de undefined

J'essaie d'afficher un composant dynamique similaire (pas exact) à l'exemple dans angular docs.

J'ai une directive dynamique avec viewContainerRef

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

Extrait du code du composant

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

Enfin ajouté <ng-template dynamicComponent></ng-template> dans le modèle

9
mperle

Vous pouvez adopter cette approche: ne créez pas de directive, donnez plutôt un identifiant à ng-template

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

utilisation @ViewChild décorateur dans votre classe de composants

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

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

J'ai eu le même problème. Vous devez ajouter la directive dans l'AppModule:

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

Dans Angular 8 mon correctif était:

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

A noté que je fais face au même problème si le sélecteur de directive (dynamicComponent dans ce cas) est à:

  1. premier élément du composant

  2. élément parent avec la condition * ngIf

Par conséquent, je l'évite en le mettant à l'intérieur au niveau de la balise non root dans le composant html et du composant load à viewContainerRef uniquement lorsque la condition correspond.

0
Ng Siow Fun