My requirement is something like, I have a reusable table which I wanna use on multiple places. I am passing table data and columns wherever I am using this table.
Now in some parent components I wanna get data when user click on table row or double click on table row.
For that I have create a directive using @HostListener.
When I am using directive on table row I can get clicked row data in directive but when I am emitting this data I am not getting it in parent.
table.component.html
<section class="example-section">
<div class="cdx-table-wrapper cdx-table-wrapper-fixed">
<table mat-table [dataSource]="tableData" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<ng-container *ngFor="let disCol of tableColumns; let colIndex = index" matColumnDef="{{disCol}}">
<th mat-header-cell *matHeaderCellDef>{{disCol}}</th>
<td mat-cell *matCellDef="let element">{{element[disCol]}}</td>
</ng-container>
<tr class="persues-table-row" mat-header-row *matHeaderRowDef="tableColumns"></tr>
<tr class="persues-table-row" mat-row *matRowDef="let row; columns: tableColumns;" appTableEvent [rowData]="row"></tr>
</table>
</div>
</section>
table-events.directive.ts
import { Directive, HostListener, Input, Output, EventEmitter } from '@angular/core';
@Directive({
selector: '[appTableEvent]'
})
export class TableEventDirective {
@Input() rowData;
@Output()
clickHandler: EventEmitter<any> = new EventEmitter();
constructor() { }
@HostListener('click', ['$event'])
onClickHandler(event: MouseEvent) {
this.clickHandler.emit(this);
}
}
parent component
<app-table
[tableData]="dataSourceBase"
[tableColumns]="displayedColumnsBase"
(clickHandler)="onRowClick($event)">
</app-table>
parent component ts
onRowClick(event) {
console.log('onRowClick', event)
}
I am not getting data in onRowClick()
method.
Now there are some cases when I just wanna use table to just show data, In that case I don't wanna apply directive.
Thanks in advance
You need to create an HostListener
on your table component as well:
@Component({
selector: 'app-table'
})
export class TableComponent {
@Output()
clickHandler: EventEmitter<MouseEvent> = new EventEmitter();
}
and have this emit from your appTableEvent
directive:
<tr class="persues-table-row" mat-row
*matRowDef="let row; columns: tableColumns;" [rowData]="row"
appTableEvent (clickHandler)="clickHandler.emit($event)">
</tr>
If you plan on having multiple of these cases, you can also go for the following solution. You would still need the clickHandler
on your TableComponent
like I showed before, but you can update your directive like this:
@Directive({
selector: '[appTableEvent]'
})
export class TableEventDirective {
@Input() rowData;
constructor(@Host() private table: TableComponent) { }
@HostListener('click', ['$event'])
onClickHandler(event: MouseEvent) {
this.table.clickHandler.emit(this);
}
}
This way you don't have to add the click handler to the <tr>
element