Some introduction:
We are currently developing an application based on Angular2 that is quite data-heavy. In order to show this data, we decided to give ngx-datatables a try.
Plenty of components will be needed showing data in grids. We added a customized footer template as well as a kind of customized header showing a page size selector using a <select>
element.
The number of markup lines grew quite a lot, therefore we would like to move the definition <ngx-datatable>
with header and footer to a separate grid component. Now we would like to reuse that component by allowing the developer using the grid to simply define the columns in markup, to have full flexibility when it comes to the column content.
The idea is to have a commonly used grid component that only asks for data as input and renders it. The typical functionality (server-side sorting and paging) in the grid should only exist once in the grid component. The component which uses the grid component should just provide the data which the grid components subscribes to, that's it.
What we have at the moment:
Common grid component with selector 'grid' defined in .ts file
<div class="gridheader">
... page size selector and other elements ...
</div>
<ngx-datatable
class="material"
[columnMode]="'force'"
[rows]="data"
[headerHeight]="'auto'"
[footerHeight]="'auto'"
[rowHeight]="'auto'"
[externalPaging]="true"
[externalSorting]="true"
[count]="totalElements"
[offset]="currentPageNumber"
[limit]="pageSize"
[loadingIndicator]="isLoading"
(page)='loadPage($event)'
(sort)="onSort($event)">
<ng-content>
</ng-content>
<ngx-datatable-footer>
<ng-template
ngx-datatable-footer-template
let-rowCount="rowCount"
let-pageSize="pageSize"
let-selectedCount="selectedCount"
let-curPage="curPage"
let-offset="offset">
<div style="padding: 5px 10px">
<div>
<strong>Summary</strong>: Gender: Female
</div>
<hr style="width:100%" />
<div>
Rows: {{rowCount}} |
Size: {{pageSize}} |
Current: {{curPage}} |
Offset: {{offset}}
</div>
</div>
</ng-template>
</ngx-datatable-footer>
</ngx-datatable>
Specific grid
<grid (onFetchDataRequired)="fetchDataRequired($event)">
<ngx-datatable-column prop="Id" name=" ">
<ng-template let-value="value" ngx-datatable-cell-template>
<a [routerLink]="['edit', value]" class="btn btn-sm btn-outline-primary">
<i class="fa fa-pencil" aria-hidden="true"></i>
</a>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="CreatedBy" prop="CreatedBy">
<ng-template let-value="value" ngx-datatable-cell-template>
{{value}}
</ng-template>
</ngx-datatable-column>
... even more columns ...
</grid>
We tried to use <ng-content></ng-content>
for the columns but no luck, the grid is just not rendered, I guess becauseno no columns are defined.
Is there a way of not repeating the same code for the grid definition over and over again and to implement some kind of wrapper that takes care of the common markup?
Grateful for any input. Thanks in advance!
Update
We managed to do it via the .ts file and a ng-template
in the markup, but we would prefer to define columns only in the markup.
Any idea anyone?
We decided to go with the solution having the column definitions in the .ts file.
Here is our solution:
Common grid component with selector 'grid' defined in .ts file
grid.component.html
grid.component.ts
Usage of this grid component wrapper
data-grid.component.html
data-grid.component.ts
The cool thing about it is, that it has commonly used templates pre-defined, e.g. for the id column (
idAnchorEditTemplate
), date columns (dateTemplate
) or date/time columns (dateTimeTemplate
). This allows maintenance of column templates that are used throughout the application in a single file.One additional type that will be needed is GridModel:
Maybe someone benefit from it someday :)