I am stuck but pretty sure what I am doing is possible.
Scenario:
I have made a common-table.component.ts that contains a mat-table (Angular Material Table) to display data.
Now I need to add buttons(with events) to it from the parent in a very generic/dynamic way. The child-component will need to update attributes or parameters on button to make it specific to that row.
Scenario Example:
Ideas so far involve passing in
CustomElement has a string html-template with events to match
or using the Renderer2-Element to change the DOM?
Renderer2 example.
https://stackblitz.com/edit/angular-gnyd4e?file=src%2Fapp%2Fapp.component.ts
or
the other way is to give ID's and in the parent use addEventListener()
But I am open for suggestions or thoughts of the best way to do this?
Ok I finally figured out a way to make it work but would still be interested in how others do it.
Summary: In the Parent Component there is an object that contains column information, I extended that with a 'button' section and included the name of the object I want executed and the parent object itself. Setting the method by itself will work but if you use any of the other private methods or passed in modules then it will throw an error. In the HTML I added a new output method but set it to '$event' instead of a method (this was the part I was missing) In the Child Component I made a new output object for the event that will be fired. Then in my HTML I loop through and build my cells while checking the button object. If there is a button, I make it and set the click event to emit the output and dynamically set the method I want to do
Parent Component
HTML
<shared-table [dataSource]="dataSource" [columnsdef]="columns" (parentMethod)="$event"></shared-table>
Typescript:
public dataSource = new MatTableDataSource <SampleTable>();
public columns: IColumn[] = [
{ id: 'title', label: 'Title'},
{ id: 'id', label: 'Id'},
{
id: 'testing',
button: {
id: "button1",
buttonText: "showAlertMessage",
clickMethodName: "alertMe",
parentClassObject: this
}
}
]
Child Component
*please note I am skipping code not relevant to answer.
HTML (inside Angular Material Table)
<ng-container [matColumnDef]="column.id" *ngFor="let column of allColumns">
<th mat-header-cell *matHeaderCellDef [fxFlex]="column.width + 'px'" mat-sort-header [ngClass]="!column.visible ? 'sr-only' : null">
{{ column.label }}
</th>
<td mat-cell *matCellDef="let row" [fxFlex]="column.width + 'px'" [ngClass]="!column.visible ? 'sr-only' : null">
<ng-container *ngIf="!column.button">
{{ row[column.id] }}
</ng-container>
<ng-container *ngIf="column.button">
<button (click)="parentMethod.emit(column.button.parentClassObject[column.button.clickMethodName](row))">
<span>{{column.button.buttonText}}</span>
</button>
</ng-container>
</td>
</ng-container>
TypeScript
@Input() dataSource: MatTableDataSource<any>;
@Input() columnsdef: IColumn[];
@Output() parentMethod = new EventEmitter<any>();