我注意到使用具有无限滚动和单元格渲染器的 ag-grid 时出现奇怪的行为。从数据源接收数据时,单元格渲染器似乎未实例化。当向下滚动直到该行在视图之外,然后向上滚动时,单元格渲染器将被实例化。我假设单元格渲染器在加载行时立即实例化,我是否遇到了错误,或者我错过了什么?
我目前正在使用ag-grid社区版本来显示只读集合。该数据由处理搜索和过滤的服务器提供。我正在使用 Angular 5.2.0、ag-grid 18.0.1 和 ag-grid-angle 18.0.1。 ag-grid 版本 17.10.0 也出现了此行为。
我已经尝试了 cellRenderer: Function(Params),并且我已经尝试了 AgRendererComponent 和 ICellRendererAngularComp。它们都只在向上滚动到该行时调用 agInit(Params)。
那么,这是一个错误还是预期的行为,如果它是一个错误,是否有已知的解决方法?感谢您的宝贵时间,这是我的代码:
从提供的地图中检索问题答案的组件,(列定义中的“字段”是问题的 id)
import { Component, ViewContainerRef } from '@angular/core';
import { AgRendererComponent } from 'ag-grid-angular';
@Component({
selector: 'editor-cell',
templateUrl: './answer.component.html'
})
export class AnswerComponent implements AgRendererComponent {
private answer: any;
private getAnswer(params: any): string {
if(params.data == null){
return;
}
if(params.data.answers == null){
return;
}
return params.data.answers[params.colDef.field]
}
agInit(params:any):void {
this.answer = this.getAnswer(params);
if(this.answer != null){
console.log("Set on init", this.answer);
}
}
refresh(params:any):boolean {
this.answer = this.getAnswer(params);
if(this.answer != null){
console.log("Set on refresh", this.answer);
}
return true;
}
}
这是我的列定义:(注意:非单元渲染器确实会立即出现,只有 cellRenderer Function 和 cellRendererFramework 不会立即加载。
{
headerName: 'messages sent',
field: 'sentMessages',
suppressFilter: true
},
{
headerName: 'work experience',
field: '57ceb64efb6b510b857e8a25',
cellRenderer: function(params){
return params.value;
if(params.node == null){
return ''
}
if(params.node.data == null){
return ''
}
if(params.node.data.answers == null){
return ''
}
if(params.node.data.answers[params.colDef.field] == null){
return ''
}
return params.node.data.answers[params.colDef.field].nl;
}
},
{
headerName: 'education',
field: '57ceb64efb6b510b857e8a26',
cellRendererFramework: AnswerComponent
},
{
headerName: 'job title',
field: '5a941e258bdfc300143cf6b0',
cellRendererFramework: AnswerComponent
}
数据源
this.datasource = {
rowCount: null,
getRows: function(params) {
ts.query({
page: Math.floor(params.startRow / 100),
size: 100,
filter: JSON.stringify(params.filterModel)
}).subscribe(
(res: HttpResponse<any[]>) => {
let data = res.body;
let lastRow = -1;
if (data.length <= params.endRow) {
lastRow = data.length;
}
params.successCallback(data, -1);
},
(res: HttpErrorResponse) => console.log(res.message));
}
};
this.rowSelection = "multiple";
this.rowModelType = "infinite";
this.maxBlocksInCache = 2;
this.infiniteInitialRowCount = 200;
this.maxConcurrentDatasourceRequests = 2;
组件 HTML
<div>
<ag-grid-angular
#agGrid
style="width: 100%; height: 500px;"
id="myGrid"
[rowData]="rowData"
class="ag-theme-balham"
[columnDefs]="columnDefs"
[datasource]="datasource"
[rowModelType]="rowModelType"
[maxBlocksInCache]="maxBlocksInCache"
[infiniteInitialRowCount]="infiniteInitialRowCount"
[maxConcurrentDatasourceRequests]="maxConcurrentDatasourceRequests"
[enableServerSideFilter]="true"
[floatingFilter]="true"
(gridReady)="onGridReady($event)"
[newRowsAction]="keep"
></ag-grid-angular>
</div>
cellRenderer
。
如本博客所述:8 个 JavaScript 性能黑客
当你在ag-Grid中滚动时,网格正在做行和列 虚拟化,这意味着 DOM 正在被废弃。这垃圾 非常耗时,如果在事件侦听器中处理,将会使 滚动体验“粗糙”。
为了解决这个问题,网格使用滚动事件去抖动 动画帧。这是实现平滑滚动的常用技巧 在这个博客中得到了很好的解释更精简、更精简、更快 带有 RequestAnimationFrame 的动画。由于这个技术很好 上面的帖子已经解释过了,这里就不再重复了。足以 比如说,我们发现这可以带来良好的性能提升。
你能解决这个问题吗