0

I try to call a dynamic component from another component but it showing me an empty page

This is the dynamic component.ts :

@Component({

selector: 'app-draw-linechart',
templateUrl: './draw-linechart.component.html',
styleUrls: ['./draw-linechart.component.css']
})
export class DrawLinechartComponent implements OnInit {
 constructor(private productservice: ProductService) {}

ngOnInit() {
     this.PrepareData(); }     
PrepareData() {
  this.productservice.getProductsData(this.productHistoric).subscribe((data) => {
     this.historicproducts = data;
     console.log("historic products", this.historicproducts)
  });}

The dynamic component.html :

 <div class="container">
<mat-grid-list cols="1" rows="2" rowHeight="100px"  >
 <mat-grid-tile>
   <mat-card class="dashboard-card">
    <mat-card-header>
      <mat-card-title>
        Line chart
      </mat-card-title>
    </mat-card-header>
  <mat-card-content class="dashboard-card-content">
    <button mat-raised-button color="warn" (click)="prepareData()">Add Line chart</button>
  </mat-card-content>
</mat-card>

This is the other component where I called the dynamic component:

export class LineChartComponent implements OnInit{
constructor(private componentFactoryResolver:ComponentFactoryResolver,private vf:ViewContainerRef){}
...
OnSubmit(){
 this.createComponent();}

createComponent(){
 let resolver = this.componentFactoryResolver.resolveComponentFactory(DrawLinechartComponent);
 this.vf.createComponent(resolver);

} Then I added the dynamic component in entryComponent of the module.ts:

entryComponents:[DrawLinechartComponent]

In the console I got the correct data but I had an empty page ( I don't know why it not reading the html code )

foufa oueslati
  • 121
  • 1
  • 11

1 Answers1

2

first, create a directive, you use this directive to any element that you want to be a container for your dynamic component:

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

@Directive({
  selector: '[ad-host]',
})
export class AdDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

in your template:

<ng-template ad-host></ng-template>

in your component:

@ViewChild(AdDirective, {static: true}) adHost: AdDirective;

and then in your function:

const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);

now your component will be created in the ng-template tag.

you can see a detailed example in angular docs

behruz
  • 570
  • 4
  • 13
  • It's a nice solution but my problem is I had in the component where I must call the dynamic component a dialog form So now with your solution the dynamic component appear but inside the form ! This is the html I had `
    ... `
    – foufa oueslati Jun 30 '20 at 09:20
  • 1
    oh. if you want to open a dialog you don't need to handle the creating of a component manually. mat dialog handles it for you. – behruz Jun 30 '20 at 09:23
  • In fact I want the dynamic component appear when I click on submit in the other component – foufa oueslati Jun 30 '20 at 09:26
  • ok just put the in the parent component, then when the user submits and closes the dialog load the dynamic component; – behruz Jun 30 '20 at 09:30
  • what ever hteml you have in your dynamic template will be placed in so wherever it is the dynamic component will load there – behruz Jun 30 '20 at 09:31