PrimeNG v18 - Table Wrapper Component, how? #2797
-
Hi, I am trying to create a re-usable table component while using p-table. import { ChangeDetectionStrategy, Component, input, signal } from '@angular/core';
import { TableActionsComponent } from '@toolbox/components/table-actions';
import { TableFilterComponent } from '@toolbox/components/table-filter';
import { TableModule } from 'primeng/table';
import { TagModule } from 'primeng/tag';
@Component({
selector: 'at-table',
templateUrl: './table.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TableActionsComponent, TableFilterComponent, TableModule, TagModule],
})
export class TableComponent<T> {
data = input.required<T[]>();
selectionMode = signal(false);
handleSearch(value: string) {
console.log('Search:', value);
}
handleSelect() {
console.log('Select');
this.selectionMode.set(!this.selectionMode());
}
handleFilter() {
console.log('Filter');
}
} <at-table-filter
(onSearch)="handleSearch($event)"
(onSelect)="handleSelect()"
(onFilter)="handleFilter()"
></at-table-filter>
<p-table [value]="data()" paginator="true" rows="5" styleClass="p-datatable-sm" showGridlines="true" stripedRows="true">
<ng-content></ng-content>
</p-table> And when I use it like below, <at-table [data]="data()">
<ng-template pTemplate="header">
<th pSortableColumn="shortCode">
Activation Policy Short Code
<p-sortIcon field="shortCode"></p-sortIcon>
</th>
<th pSortableColumn="salesChannel">
Sales Channel
<p-sortIcon field="salesChannel"></p-sortIcon>
</th>
<th pSortableColumn="billingAccountCreationType">
Billing Account Creation Type
<p-sortIcon field="billingAccountCreationType"></p-sortIcon>
</th>
<th pSortableColumn="provisionOrderCreationType">
Provision Order Creation Type
<p-sortIcon field="provisionOrderCreationType"></p-sortIcon>
</th>
<th class="w-20"></th>
</ng-template>
<ng-template pTemplate="body" let-item>
<td>
<div class="flex flex-col items-start">
<p-tag [value]="'#' + item.id" severity="secondary" styleClass="mb-4"></p-tag>
{{ item.shortCode }}
</div>
</td>
<td>
{{ item.salesChannel }}
</td>
<td>
{{ item.billingAccountCreationType }}
</td>
<td>
{{ item.provisionOrderCreationType }}
</td>
<td>
<at-table-actions [actions]="item.actions"></at-table-actions>
</td>
</ng-template>
</at-table> The p-table component isn't displaying anything. Am I doing something wrong, or is it not possible to use it this way? The project is using Angular 18.2.6, PrimeNG 18.0.0-beta.2, and experimental zoneless change detection, without importing zone.js. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
@denizguzel Hi. You can use ContentChild to access a template from the content part of the parent component: @ContentChild('headerTemplate') headerTemplate!: TemplateRef<any>;
@ContentChild('bodyTemplate') bodyTemplate!: TemplateRef<any>; Example code: Essentially this is what the PrimeNg table also does in the underlying logic: First, capture the incoming templates: Then use it with ngTemplateOutlet |
Beta Was this translation helpful? Give feedback.
@denizguzel Hi.
Oh yes, I didn't consider the directives in my example.
I updated it for you to make it work: https://stackblitz.com/edit/yamuh2?file=src%2Fapp%2Ftree-table-basic-demo.ts
Using a factory function to provide the Table ensures that the data table property is correctly instantiated and available within the component's context. This resolves the NullInjectorError because the Table provider is explicitly defined and linked to the actual instance of the data table created in the component.
Things are getting complex, unfortunately. At this point, if I were you I would start to consider is this the right way to create reusable components. According to my experience, this might ad…