Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Component inside ngx-datatable row-detail

I'm creating a reusable datatable using ngx-datatable and I would like to have dynamic components rendered inside the row detail. The datatable component receives a component class as an argument from a parent module and I use ComponentFactory to createComponent. I can see that the constructor and the onInit methods are running for the dynamic component but it is not being attached to the DOM.

This is what the datatable html looks like for the row-detail :

 <!-- [Row Detail Template] -->
        <ngx-datatable-row-detail rowHeight="100" #myDetailRow (toggle)="onDetailToggle($event)">
          <ng-template let-row="row" #dynamicPlaceholder let-expanded="expanded" ngx-datatable-row-detail-template>
          </ng-template>
        </ngx-datatable-row-detail>
 <!-- [/Row Detail Template] -->

And this is what my .ts file looks like :

@ViewChild('myDetailRow', {static: true, read: ViewContainerRef}) myDetailRow: ViewContainerRef;
@ViewChild('dynamicPlaceholder', {static: true, read: ViewContainerRef}) dynamicPlaceholder: ViewContainerRef;

renderDynamicComponent(component) {
        var componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
        var hostViewConRef1 = this.myDetailRow;
        var hostViewConRef2 = this.dynamicPlaceholder;
        hostViewConRef1.createComponent(componentFactory);
        hostViewConRef2.createComponent(componentFactory);
}

Another point is that if my #dynamicPlaceholder ng-template is placed outside of ngx-datatable, it works and the dynamic module is rendered and displayed.

like image 643
Raghav Kanwal Avatar asked Dec 26 '19 07:12

Raghav Kanwal


1 Answers

We can't render a component into a Template (<ng-template>) at runtime with createComponent
because afaik templates get processed by Angular at compile time. So we need a solution that works at compile time.


Solution with drawbacks

ng-content can help us here:

<!-- [Row Detail Template] -->
<ngx-datatable-row-detail rowHeight="100" (toggle)="onDetailToggle($event)">
   <ng-template let-row="row" let-expanded="expanded" ngx-datatable-row-detail-template>
      <ng-content></ng-content>
   </ng-template>
</ngx-datatable-row-detail>
<!-- [/Row Detail Template] -->

We can then pass anything we want to the detail view:

<my-table>From the ouside but I cant access the current row :(</my-table>

But there is a problem: We can't use ng-content when we want to access the current row in the passed template.


Solution

But ngx-datatable got us covered. We can pass a template to thengx-datatable-row-detail directive:

<ngx-datatable-row-detail [template]="myDetailTemplate "rowHeight="100" (toggle)="onDetailToggle($event)">
</ngx-datatable-row-detail>

The template can then be passed into from any component on the outside via a @Input variable:

<ng-template #myDetailTemplate let-row="row">
  From the outside with access to the current row: {{row.name}}
</ng-template>

Take a look at the stackblitz, where I wrote a my-table component as poc.

like image 196
ChrisY Avatar answered Nov 15 '22 21:11

ChrisY