How to Render an Angular routerLink inside the cell of an ag-Grid?
Asked Answered
S

3

8

The link I am trying to render looks like this when I just try to render it on a basic HTML page:

<a [routerLink]="['/leverance/detail', 13]">A new link</a>

When trying to render it on the ag-Grid, I try to do like below:

src\app\leverancer\leverancer.component.ts

ngOnInit() {
    this.dataGridColumnDefs = [
          { 
            headerName: 'Type', 
            field: 'leveranceType.name', 
            width: 150,
            cellRenderer: this.customCellRendererFunc       
          }
    ];
}

customCellRendererFunc(params): string {
  const cellContent `<a [routerLink]="['/leverance/detail', 13]">A new link</a>`;
  return cellContent;
}

but I don't see a working routerLink in my ag-Grid. Can you tell me what I need to do to render a working routerLink in my ag-Grid?

Sisely answered 18/12, 2018 at 16:46 Comment(0)
C
6

I think cellRenderer only supports normal HTML (without any angular-specific stuff).

You want to use cellRendererFramework as seen in these examples:

Since you use RouterLink, you probably need RouterModule in the moduleImports

Candace answered 18/12, 2018 at 16:56 Comment(1)
Thank you for your tip :) I have found a resource by Michael Karén, where, apparently, he uses cellRendererFramework and makes a RouterLinkRendererComponent: medium.com/ag-grid/… stackblitz.com/edit/…Sisely
C
1

I created a generic component that is usable for any link cell.

Usage

columnDefs = [
  {
    colId: 'My Column',
    cellRendererFramework: AgGridLinkCellComponent,
    cellRendererParams: {
      // `text` and `link` both accept either an string expression (same as `field`) or a function that gets ICellRendererParams
      text: 'title',
      link: (params: ICellRendererParams) => `/my-path/${_.get(params, 'data.id')}`
    }
  }
]

Register the component in your AppModule:

imports: [
    AgGridModule.withComponents([
      AgGridLinkCellComponent
    ])
]

The component itself:

import * as _ from 'lodash';
import {Component} from '@angular/core';
import {AgRendererComponent} from 'ag-grid-angular';
import {ICellRendererParams} from 'ag-grid-community';

@Component({
  selector: 'app-ag-grid-link-cell-component',
  template: '<a [routerLink]="link">{{ text }}</a>',
})
export class AgGridLinkCellComponent implements AgRendererComponent {
  link: string;
  text: string;

  constructor() {
  }

  agInit(params: ICellRendererParams): void {
    this.refresh(params);
  }

  refresh(params: ICellRendererParams): boolean {
    const dataParams = params.colDef.cellRendererParams;
    this.link = _.isFunction(dataParams.link) ? dataParams.link(params) : _.get(params.data, dataParams.link);
    this.text = _.isFunction(dataParams.text) ? dataParams.link(params) : _.get(params.data, dataParams.text);
    return false;
  }
}
Cytology answered 27/8, 2021 at 11:28 Comment(0)
R
0

Here is solution. I tried it with angular 7 and its work fine for me.

ag grid provides events and callbacks onCellClicked and cellRendere are two of them.

problem with onCellCliecked and cellRendere is that they work on JS. so the this object associated with these callbacks will be a JS instance.

But for angular to call functions or route any url we'll be need of instance of angular component which no available in those callbacks

so Here is solution to get that angular instance to work with component.

Typescript stores instance of current object in _this whenever this is not available. we can get instance of angular component by

const self = eval('_this');

this self will hold instance of angular component so we can call any function or service from angular component and also we can self.router.navigateByUrl(url)

here is example

{field: 'plan', headerName: 'Plan Case', sortable:true,filter:true,
  cellRenderer:function(paramObj){
    //for making cell as link
    return `<a href="javascript:void(0)" >Plan Case</a>`;
  }, 
  onCellClicked:function(data){
    const self = eval('_this');
    //navigating on clicking on cell
    self.router.navigateByUrl('YOUR_URL');
  }  
},

Alternatively you can call any angular function from onCellClicked event. example

onCellClicked:function(data){
        const self = eval('_this');
        //calling test function from angular component.
        self.test(data.data);
      } 

Thanks

Rivalee answered 26/6, 2020 at 7:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.