Ag Grid 单元格渲染器直到滚动回视图时才实例化
Ag Grid cell renderer not instantiated until scrolled back in view
我注意到在将 ag-grid 与无限滚动和单元格渲染器一起使用时出现奇怪的行为。当从数据源接收到数据时,单元格渲染器似乎没有被实例化。当向下滚动直到该行超出视图,然后向上滚动时,单元格渲染器被实例化。我会假设单元格渲染器在加载行时立即实例化,我是遇到错误还是遗漏了什么?
我目前正在使用 ag-grid 社区版来显示只读集合。此数据由处理搜索和过滤的服务器提供。我使用的是 Angular 5.2.0,ag-grid 18.0.1 和 ag-grid-angular 18.0.1。此行为也出现在 ag-grid 版本 17.10.0 中。
我已经尝试了 cellRenderer: Function(Params),并且我已经尝试了 AgRendererComponent 和 ICellRendererAngularComp。他们都只在向上滚动到该行时调用 agInit(Params)。
那么,这是错误还是预期的行为,如果是错误,是否有已知的解决方法?谢谢你的时间,这是我的代码:
从提供的地图中检索问题答案的组件,(列定义中的 'field' 是问题的 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 函数和 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 Performance Hacks for JavaScript
When you scroll in ag-Grid, the grid is doing row and column
virtualisation, which means the DOM is getting trashed. This trashing
is time consuming and if processed within the event listener will make
the scroll experience 'rough'.
To get around this, the grid uses debouncing of scroll events with
animation frames. This is a common trick to achieve smooth scrolling
and is explained very well in this blog Leaner, Meaner, Faster
Animations with RequestAnimationFrame. As this technique is well
explained in posts such as above, I won't repeat it here. Suffice to
say, we found this delivers a good performance boost.
我还建议您完成 this document regarding Performance provided by ag-grid
我注意到在将 ag-grid 与无限滚动和单元格渲染器一起使用时出现奇怪的行为。当从数据源接收到数据时,单元格渲染器似乎没有被实例化。当向下滚动直到该行超出视图,然后向上滚动时,单元格渲染器被实例化。我会假设单元格渲染器在加载行时立即实例化,我是遇到错误还是遗漏了什么?
我目前正在使用 ag-grid 社区版来显示只读集合。此数据由处理搜索和过滤的服务器提供。我使用的是 Angular 5.2.0,ag-grid 18.0.1 和 ag-grid-angular 18.0.1。此行为也出现在 ag-grid 版本 17.10.0 中。
我已经尝试了 cellRenderer: Function(Params),并且我已经尝试了 AgRendererComponent 和 ICellRendererAngularComp。他们都只在向上滚动到该行时调用 agInit(Params)。
那么,这是错误还是预期的行为,如果是错误,是否有已知的解决方法?谢谢你的时间,这是我的代码:
从提供的地图中检索问题答案的组件,(列定义中的 'field' 是问题的 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 函数和 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 Performance Hacks for JavaScript
When you scroll in ag-Grid, the grid is doing row and column virtualisation, which means the DOM is getting trashed. This trashing is time consuming and if processed within the event listener will make the scroll experience 'rough'.
To get around this, the grid uses debouncing of scroll events with animation frames. This is a common trick to achieve smooth scrolling and is explained very well in this blog Leaner, Meaner, Faster Animations with RequestAnimationFrame. As this technique is well explained in posts such as above, I won't repeat it here. Suffice to say, we found this delivers a good performance boost.
我还建议您完成 this document regarding Performance provided by ag-grid