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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With