Workaround for Angular2 event-binding in ag-grid cell templates

Angular2 feels like a stable framework, but I was recently reminded of its beta status when trying to use the agnostic data-grid ag-grid to detect button clicks in a cell template - a simple enough task in the first Angular. It transpires that since the major re-write ag-grid is unable to access the Angular2 compiler at runtime, preventing it from being able to compile cell templates.

Warning notice from ag-grid's website

Since you can't use (click)="onButtonClicked($event)" on the buttons, the workaround is instead to detect the button's click event as it bubbles up the parent nodes by listening for the rowClicked event on the table. It's then just a case of drilling into the DOM event to determine what button was clicked in the cell.

<ag-grid-ng2 #agGrid class="ag-fresh"
    rowHeight="10"

    [columnDefs]="columnsDefs"
    [rowData]="rowData"

    (rowClicked)="onRowClicked($event)">
</ag-grid-ng2>

The onRowClicked function in the component will then be passed the event when any element in the row is clicked. You can then determine if a button click was the cause of the event firing by checking for the presence of a custom attribute on the target element, and if present, using the value of this attribute to differentiate between the buttons.

@Component({
    directives: [AgGridNg2],
    selector: "user-table",
    templateUrl: "../user-table.subhtml"
})
export class TableComponent {
    public columnDefs = [
        { headerName: "Username", field: "username" },
        { headerName: "Actions",
          suppressMenu: true,
          suppressSorting: true,
          template:
            `<button type="button" data-action-type="view" class="btn btn-default">
               View
             </button>

            <button type="button" data-action-type="remove" class="btn btn-default">
               Remove
            </button>`
        }
    ];

    public onRowClicked(e) {
        if (e.event.target !== undefined) {
            let data = e.data;
            let actionType = e.event.target.getAttribute("data-action-type");

            switch(actionType) {
                case "view":
                    return this.onActionViewClick(data);
                case "remove":
                    return this.onActionRemoveClick(data);
            }
        }
    }

    public onActionViewClick(data: any){
        console.log("View action clicked", data);
    }

    public onActionRemoveClick(data: any){
        console.log("Remove action clicked", data);
    }
}