I have an Angular 13
app & building a common reusable component named app-table
html
<table >
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>DOB</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of tableItems">
<td> {{ item.name }}</td>
<td> {{ item.email } </td>
<td> {{ item.dob }} </td>
</tr>
</tbody>
</table>
component.ts
import { Component, Input, OnInit} from '@angular/core';
import { TableItem } from './model/tableItem';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css'],
})
export class TableComponent implements OnInit {
@Input() tableItems: TableItem[] = [];
constructor() {}
ngOnInit(): void {}
}
Currently, this is reusable across 4-5 places, however reusability of this component is tied to name
, email
, dob
fields. I want to make it generic so that any model could be linked to this component & can be reused across the app.
Please suggest. Thanks!
CodePudding user response:
There are a lot of ways to do it, the simplest one would be add another input which accepts a list of columns, then you can populate your table header based on that list. something like this.
<table >
<thead>
<tr>
<ng-container *ngFor="let column of columns">
<th>{{column}}</th>
</ng-container>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of tableItems">
<ng-container *ngFor="let column of columns">
<td>{{item[column]}}</td>
</ng-container>
</tr>
</tbody>
</table>
and your component will look like this.
columns = ['name','email','dob']
tableItems = [
{
name: 'test',
dob: '31/12/1990',
email: '[email protected]'
}
];
but table components are really difficult to maintain and extend, they require a lot of effort, it's not something you casually do. I would suggest finding a library that built a really good table component and using it, depending on your requirements, few examples would be ngx easy table, angular cdk table, and so on.
CodePudding user response:
You can get the column names from object keys and iterate over them using *ngFor
, for example:
In your TableComponent
template file
<table>
<thead>
<tr>
<th *ngFor="let header of data[0] | keyvalue: sortNull">{{ header.key }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data">
<td *ngFor="let cell of row | keyvalue: sortNull">{{ cell.value }}</td>
</tr>
</tbody>
</table>
And in typescript file
export class TableComponent {
@Input() data: any[] = [];
sortNull() { return 0; }
}
sortNull()
is just a compartor function that always return 0
to maintain the order of insertion for your key/value pairs
And for usage
@Component({
selector: 'app-user-list',
template: `<app-table [data]="data"></app-table>`
})
export class UserListComponent {
data = [
{ name: 'John', email: '[email protected]', dob: '2001/01/01' },
{ name: 'Jane', email: '[email protected]', dob: '2002/02/02' },
{ name: 'Kane', email: '[email protected]', dob: '2003/03/03' },
]
}