Given the app-data-table component:
<p-dataTable [value]="items">
<ng-content></ng-content>
<footer>
<button type="button" pButton icon="fa-refresh" label="Refresh" (click)="onRefresh()"></button>
</footer>
</p-dataTable>
and its usage:
<app-data-table [items]="items" (refresh)="onRefresh()">
<p-column field="name" header="Name"></p-column>
<p-column field="address" header="Address"></p-column>
</app-data-table>
the columns ain't shown.
This is not related to PrimeNG, it seems to be related to Angular 2 itself better to ask this at Angular 2 side. Note that we use @ContentChildren to get columns, it seems ng-content projection does not provide those. You may trying getting the children yourself with @ContentChildren and passing it to the datatable programmatically e.g. datatable.columns = //columns that you get from ContentChildren.
I also needed this, so I tried @cagataycivici's suggestion to try overwriting the columns. I got it working, but only by overwriting the ngAfterContentInit method on DataTable, which seems a little hacky:
const originalDatatableNgAfterContentInit = this.datatable.ngAfterContentInit;
this.datatable.ngAfterContentInit = () => {
this.datatable.cols = this.cols;
originalDatatableNgAfterContentInit.call(this.datatable);
};
Here's a plunkr: http://embed.plnkr.co/0QQD7WUksrrrFg6BUKKh/
Is there a cleaner way of doing this?
@treythomas123: Thanks for your comment, this works.
However, this approach does not seem to work for the footer (setting it via datatable.footer = //from contentchildren). Is there any other possibility?
you found a solution for the footer (or another way to add the footer/columns)?
As for the columns, it was solved like this:
export class DataTableComponent implements AfterViewInit {
...
@ViewChild(DataTable) private dataTable: DataTable;
@ContentChildren(Column) protected columns: QueryList<Column>;
...
ngAfterViewInit() {
this.dataTable.cols = this.columns;
this.dataTable.ngAfterContentInit();
}
...
As for the footer, like this:
<p-dataTable [value]="items" selectionMode="single" [(selection)]="selectedItem">
<footer>
<button type="button" pButton icon="fa-refresh" title="Refresh" (click)="onRefresh()"></button>
<button type="button" pButton icon="fa-plus" title="Add" (click)="onAdd()"></button>
<button type="button" pButton icon="fa-edit" title="Edit" (click)="onEdit()" [disabled]="selectedItem == null"></button>
<button type="button" pButton icon="fa-trash" title="Delete" (click)="onDelete()" [disabled]="selectedItem == null"></button>
<ng-content select=".data-table-buttons"></ng-content>
</footer>
</p-dataTable>
usage:
<app-data-table [service]="service" (save)="onSave($event)" (setArrayElements)="onSetArrayElements($event)" editDialogWidth="500">
...
<span class="data-table-buttons">
<button type="button" pButton icon="fa-key" title="Set password" (click)="isSetPasswordDialogVisible = true" [disabled]="dataTable.selectedItem == null"></button>
</span>
</app-data-table>
Altering the datatable columns in the AfterViewInit phase will result in an ExpressionChangedAfterItHasBeenCheckedError. I would prefer a cleaner solution, but can't seem to find one. It doesn't seem to be a problem with angular either. I've created some test components mimicking the issue and the ng-content projection works fine in those.
Most helpful comment
I also needed this, so I tried @cagataycivici's suggestion to try overwriting the columns. I got it working, but only by overwriting the
ngAfterContentInitmethod on DataTable, which seems a little hacky:Here's a plunkr: http://embed.plnkr.co/0QQD7WUksrrrFg6BUKKh/
Is there a cleaner way of doing this?