Ag网格链接与单元格中的链接



我正在使用Ag-Grid构建Angular 4应用程序,并且我正在尝试弄清楚如何在单元格中添加链接。有人可以帮助我解决这个问题吗?谢谢

请检查此演示

cellRenderer: function(params) {
  return '<a href="https://www.google.com" target="_blank" rel="noopener">'+ params.value+'</a>'
}

在此演示中,列"城市"的单元格值是超链接。

我前几天都在努力,这比我首先想到的要复杂得多。我最终创建了一个渲染器组件,然后在该链接中发送给该组件,这需要在Ngzone Magic上进行一些工作。您可以在列定义中使用它:

cellRendererFramework: RouterLinkRendererComponent,
cellRendererParams: {
    inRouterLink: '/yourlinkhere',
}

组件是您发送的链接,而params.value是单元格值。这意味着您可以路由到可以看起来像"您的link/:id"的角路线。如果您不想要更通用的解决方案,也可以通过不发送链接中的链接而只是对模板中的链接进行硬编码而不使用CellRendererParams。

import { Component, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { AgRendererComponent } from 'ag-grid-angular';
@Component({
    template: '<a [routerLink]="[params.inRouterLink,params.value]"  (click)="navigate(params.inRouterLink)">{{params.value}}</a>'
})
export class RouterLinkRendererComponent implements AgRendererComponent {
    params: any;
    constructor(
        private ngZone: NgZone,
        private router: Router) { }
    agInit(params: any): void {
        this.params = params;
    }
    refresh(params: any): boolean {
        return false;
    }
    // This was needed to make the link work correctly
    navigate(link) {
        this.ngZone.run(() => {
            this.router.navigate([link, this.params.value]);
        });
    }
}

并在

中注册
@NgModule({
    imports: [
        AgGridModule.withComponents([
            RouterLinkRendererComponent,
        ])
    ],
})

更新:我写了一篇博客文章:-links-34FA57CA2952

这有点过时,但可能会对某人有所帮助。在Angular 5上使用打字稿的解决方案类似于C.O.G所建议的解决方案。在组件的打字稿文件中,列定义可以包含自定义单元渲染函数。

 columnDefs  = [
    {headerName: 'Client', field: 'clientName' },
    {headerName: 'Invoice Number', field: 'invoiceNumber',
        cellRenderer: (invNum) => 
              `<a href="/invoice/${invNum.value}" >${invNum.value}</a>` },
];

在渲染单元格时调用lambda函数。传递的参数的"值"是您可以用来生成自定义渲染的方法。

@michaelKarén

启发

这是一个更灵活的改进版本。

  • 我们可以设置要在链接中显示的文本
  • 我们可以通过2个路由器链接参数
  • 根据数据解决RouterLink
  • 支持目标
  • 仅在不适用链接时显示文本
  • 等等,如果您想添加,请进一步编辑此组件
import { Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
export interface IRouterLinkRendererComponentOptions {
    routerLinkParams?: any[];
    linkDescription?: string;
    textOnly?: string;
    target?: string;
}
@Component({
    template: `
        <a *ngIf="params.textOnly == null; else textOnlyBlock" 
           [routerLink]="params.routerLinkParams" 
           [target]="params.target ? params.target : '_self'"
        >
            {{ params.linkDescription }}
        </a>
        
        <ng-template #textOnlyBlock>
            {{ params.textOnly }}
        </ng-template>
    `
})
export class RouterLinkRendererComponent implements ICellRendererAngularComp {
    params: IRouterLinkRendererComponentOptions;
    agInit(params: any): void {
        this.params = params.routerLinkRendererComponentOptions(params);
    }
    refresh(params: any): boolean {
        return true;
    }
}

,我们才能在

列定义中需要动态解析参数并返回文本。
{
...
    cellRendererFramework: RouterLinkRendererComponent,
    cellRendererParams: {
        routerLinkRendererComponentOptions: (param): IRouterLinkRendererComponentOptions => {
            if (param.data.dispatch_adjustment) {
                return {
                    routerLinkParams: ['/adjustments', param.data.dispatch_adjustment.id, 'edit'],
                    linkDescription: '#' + param.data.dispatch_adjustment.id
                };
            } else {
                return {
                    textOnly: '-'
                };
            }
        }
    },
...
},

而不是在CellRenderer中使用HREF,最好将CellRenderer Framework用作路由链接在其中工作。另一个缺点是,如果您使用HREF,那么整个Angular应用程序将再次重新加载,它将导航状态从势在必行更改为popstate。角路由器在命令状态下起作用。

我实现了与迈克尔和汤姆相似的东西,只有[routerLink],没有(click)处理程序。但是最近我开始得到可怕的警告:

Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?

尝试了一段时间后,我找到了这篇文章,并添加了导航点击处理程序功能,这使应用程序再次开始工作,但是我发现" 导航"触发了Angular区域之外的消息'消息仍在出现在日志中。

因此,当(click)="navigate()"调用触发ngZone内的导航时,[routerLink]调用仍在进行,这困扰着我。我真的不希望两次尝试导航发生 - 如果未来的API更新发生了任何变化。

我决定用跨度 pseudoLink替换锚标签。

.pseudoLink {
  color: blue;
  text-decoration: underline;
  cursor: pointer;
}
@Component({
   template: '<span class="pseudoLink" (click)="navigate()">{{mytitle}}</span>'
})
navigate() {
  this.ngZone.run(
    () => {
      console.log("LinkRendererComponent: navigate: (", this.mylink, ")");
      this.router.navigate([this.mylink]);
    }
  );
}

this.mylink是根据cellRendererParams传递的参数在agInit()方法中定义的。

这对于我的主要目的来说很好,即使单元格看起来像一个链接。我唯一失去的是浏览器状态栏中的URL路径弹出窗口。

希望这可以帮助别人。

使用单元渲染器是正确的解决方案,但最高答案中缺少的是停止点击事件到达aggrid:

cellRenderer: ({value}) => {
    const a = document.createElement('a');
    a.innerText = a.href = value;
    a.target = '_blank';
    // Prevent click from reaching AgGrid
    a.addEventListener('click', event => { event.stopPropagation() });
    return a;
}

如果点击泡起来要粘合到粘合剂,它将导致行选择更改,如果启用了这些。

我创建了一个通用组件,该组件可用于任何链接单元,不使用解决方法,并且没有记录任何警告。

用法

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')}`
    }
  }
]

在您的AppModule中注册组件:

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

组件本身:

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;
  }
}

我们遇到了这个问题,它并不简单。
当我们在Ag-Grid上使用适应性时,我们最终以不同的方式解决了它。因此,我们创建了一个适应性的动作列,并在启用功能中提供了链接。这对我们来说最有效,因为我们不总是希望链接出现,因此我们可以使用NorkeRender函数来决定我们是否要显示每行的链接。

最新更新