Reputation: 1819
I have the following Angular Material mat-table
for listing Employees. I also have other tables I need to convert to this same style and structure. How can I componentize this Employee table for reuse? The point of using a component library like Material is to reuse common components, I'm having trouble understanding how this table can be reused easily.
<table mat-table matSort [dataSource]="employeeDisplayList" class="mat-elevation-z8 table">
<ng-container matColumnDef="selected">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element; let i = index"
[ngClass]="{'dependent': element.relationship !== 'Primary'}">
<input type="checkbox" id="enrollEmployee-{{ i }}" name="enrollEmployee">
<label for="enrollEmployee-{{ i }}"></label>
</td>
</ng-container>
<!-- Employee Name Column -->
<ng-container matColumnDef="employeeName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Employee Name </th>
<td mat-cell *matCellDef="let element"
[ngClass]="{'dependent': element.relationship !== 'Primary'}"> {{element.employeeName}} </td>
</ng-container>
<!-- Relationship Column -->
<ng-container matColumnDef="relationship">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Relationship </th>
<td mat-cell *matCellDef="let element"
[ngClass]="{'dependent': element.relationship !== 'Primary'}"> {{element.relationship}} </td>
</ng-container>
<!-- Medical Column -->
<ng-container matColumnDef="medical">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Medical </th>
<td mat-cell *matCellDef="let element"
[ngClass]="{'dependent': element.relationship !== 'Primary'}"> {{element.medical}} </td>
</ng-container>
<!-- Plan Name Column -->
<ng-container matColumnDef="planName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Plan Name </th>
<td mat-cell *matCellDef="let element"
[ngClass]="{'dependent': element.relationship !== 'Primary'}"> {{element.planName}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
TS:
displayedColumns: string[] = ['selected', 'employeeName', 'relationship', 'medical', 'planName'];
@ViewChild(MatSort) sort: MatSort;
ngOnInit() {
this.employeeList = this.enrollmentService.getEmployees();
this.employeeDisplayList = new MatTableDataSource(this.employeeList);
this.employeeDisplayList.sort = this.sort;
}
Upvotes: 0
Views: 1223
Reputation: 57909
the first step is "parametrize" your table. For this, you can use an array of object and auxliar variable
You give a few clues, but I can imagine you can has, e.g.
//an array like
columnSchema=[
{title:"Employed Name",column:"employeeName"}
{title:"Relationship ",column:"relationship}
...
]
//two variables
columnCompare="relationship"
valueCompare="Primary"
//your displayColumns is realional with columSchema
displayColumns=["selected",...this.columSchema.map(x=>x.column)]
//and use datasource as data source
Then you can create your table like
<table mat-table matSort [dataSource]="dataSource" class="mat-elevation-z8 table">
<!--the "selected is fixed for all the tables-->
<ng-container matColumnDef="selected">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element; let i = index"
[ngClass]="element[columnCompare]==valueCompare?'dependent':null">
<input type="checkbox" id="enrollEmployee-{{ i }}" name="enrollEmployee">
<label for="enrollEmployee-{{ i }}"></label>
</td>
</ng-container>
<!--the rest columns use the columnSchema-->
<ng-container *ngFor="let column of columnSchema" [matColumnDef]="column.column">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{column.title}}</th>
<td mat-cell *matCellDef="let element"
[ngClass]="element[columnCompare]==valueCompare?'dependent':null">
{{element[column.column]}}
</td>
</ng-container>
...
</table>
Well, we need now convert ours variables in @Input
of our component, as displayColumns depending of "columnSchema" use a setter
displayColumns;
_columnSchema;
@Input() dataSource
@Input() columnCompare
@Input() valueCompare
@Input() set columnSchema(value)
{
this._columnsSchema=value
this.displayColumns=["selected",...value.map(x=>x.column)]
}
get columnSchema()
{
return this._columnSchema
}
Well, create a component and use like
<myComponent
[dataSource]="employeeDisplayList"
[columnSchema]="columnSchema"
[columnCompare]="'relationship'"
[valueCompare]="'Primary'">
</myComponent>
There are a lot of more things you can do it, but I hope this help you a few
Upvotes: 3