我正在使用ag-grid构建angular 4应用程序,并且在尝试将链接放入单元格时遇到了问题。有人可以帮我解决这个问题吗? 谢谢
我正在使用ag-grid构建angular 4应用程序,并且在尝试将链接放入单元格时遇到了问题。有人可以帮我解决这个问题吗? 谢谢
cellRenderer: function(params) {
return '<a href="https://www.google.com" target="_blank" rel="noopener">'+ params.value+'</a>'
}
在此演示中,“city”列的单元格值是超链接。
Country
是一个超链接。 - onetwo12我前几天遇到了这个问题,它比我最初想象的要复杂一些。最终我创建了一个渲染器组件,向其中发送链接,并且需要一些 NgZone 魔法才能完全运行。你可以像这样在列定义中使用它:
cellRendererFramework: RouterLinkRendererComponent,
cellRendererParams: {
inRouterLink: '/yourlinkhere',
}
组件中,inRouterLink 是您发送的链接,params.value 是单元格的值。这意味着您可以路由到您的 Angular 路由,它可能看起来像“yourlink/: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,
])
],
})
更新:我已经写了一篇关于此事的博客文章:https://medium.com/ag-grid/enhance-your-angular-grid-reports-with-formatted-values-and-links-34fa57ca2952
RouterLinkRendererComponent
添加到模块中作为entryComponent。entryComponents: [ RouterLinkRendererComponent ]
。否则,您将收到大量的ag-grid渲染错误。 - hastrb这篇文章有点过时,但可能会对某些人有所帮助。在 Angular 5 中使用 TypeScript 的解决方案类似于 C.O.G 建议的方法。在组件的 TypeScript 文件中,列定义可以包含自定义的单元格渲染函数。
columnDefs = [
{headerName: 'Client', field: 'clientName' },
{headerName: 'Invoice Number', field: 'invoiceNumber',
cellRenderer: (invNum) =>
`<a href="/invoice/${invNum.value}" >${invNum.value}</a>` },
];
lambda函数是在呈现单元格时调用的。传递的参数“value”是可以用于生成自定义渲染的值。href
和routerLink
是完全不同的故事...我会创建一个简单的组件,在模板中用routerLink
包装它,然后将此组件作为列添加到columnDefs
中。这几乎与Michael上面建议的相同。 - hastrb受@Michael Karén启发
这是一个更灵活的改进版本。
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框架作为路由链接。另一个缺点是,如果使用href,则整个Angular应用程序将重新加载,从命令式导航状态更改为popstate。Angular路由器基于命令式状态工作。
我曾经实现了类似Michael和Tom的东西,只使用[routerLink]
而没有(click)
处理程序。 但是最近我开始收到令人恐惧的警告:
Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?
(click)="navigate()"
调用会在ngZone
内触发导航,但[routerLink]
调用仍然会被执行,这让我感到困扰。我真的不希望发生两次尝试导航——以防未来API更新时发生任何变化。.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
是在 agInit()
方法中根据通过 cellRendererParams
传递的参数定义的。
这对于使单元格看起来像链接的主要目的很有效。唯一失去的是浏览器状态栏中的URL路径弹出。
希望这可以帮助其他人。
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;
}
}