I update my data outside of Ag-Grid related code. I have a variable, this.works
, which stores all of the user's "portfolio" for my portfolio manager project. I have this.loadMore()
which loads in more data from the server (which I do not have access to, which is why I load data externally).
I'm employing the "infinite" row model to have infinite scroll. I started using datasource because I want to use sorting and filtering, too.
The problem is that when I update the datasource, scrolling gets reset to the top. This is very annoying behaviour.
Using Ag-Grid Community and Vue.js.
GridOptions (set in beforeMount())
this.gridOptions = {
suppressScrollOnNewData: true,
rowSelection: 'single',
rowModelType: 'infinite',
deltaRowDataMode: true,
defaultColDef: {
sortable: false,
resizable: true
},
columnTypes: {
'imageColumn': {
width: 150,
sortable: false,
autoHeight: true,
cellRendererFramework: AgGridImageFormatter
},
'priceColumn': {
cellRendererFramework: AgGridPriceFormatter
}
}
};
Methods:
({
methods: {
onBodyScroll: function(event) {
var lastDisplayedWork, ref, worksCount;
worksCount = this.works.length;
lastDisplayedWork = (ref = this.gridOptions.api) != null ? ref.getLastDisplayedRow() : void 0;
if (worksCount - 2 < lastDisplayedWork) {
event.api.ensureIndexVisible(worksCount - 2);
this.loadMore();
return event.api.setDatasource(this.gridDatasource);
}
},
CreateAgGridDataSource: function(worksData) {
return {
rowCount: this.works.length,
getRows: (function(_this) {
return function(params) {
var lastRow, rowsThisPage;
rowsThisPage = _this.works.slice(params.startRow, params.endRow);
lastRow = -1;
return params.successCallback(rowsThisPage, lastRow);
};
})(this)
};
},
onRowSelected: function(event) {
return this.workClicked(event.data.id);
},
onGridReady: function(event) {
this.gridDatasource = this.CreateAgGridDataSource(this.works);
return event.api.setDatasource(this.gridDatasource);
}
}
});
Apologies for any weird JS code, I'm using a CoffeeScript to JS converter. I think it should be ok though.
HTML:
<div id="gridContainer">
<ag-grid-vue class="ag-theme-balham" id="AgGrid" :gridOptions="gridOptions" :modules="agGridModules" :columnDefs="agGridColDefs" @body-scroll="onBodyScroll" @row-selected="onRowSelected" @grid-ready="onGridReady"></ag-grid-vue>
</div>
How can I make sure that the scroll stays wherever the user has scrolled to? For the record, using api.refreshCells()
doesn't work. With that I get blank rows after the first data call (so only the first ~23 or so items display). So, I need to "refresh" the datasource each time new data is fetched.
I update my data outside of Ag-Grid related code. I have a variable, this.works
, which stores all of the user's "portfolio" for my portfolio manager project. I have this.loadMore()
which loads in more data from the server (which I do not have access to, which is why I load data externally).
I'm employing the "infinite" row model to have infinite scroll. I started using datasource because I want to use sorting and filtering, too.
The problem is that when I update the datasource, scrolling gets reset to the top. This is very annoying behaviour.
Using Ag-Grid Community and Vue.js.
GridOptions (set in beforeMount())
this.gridOptions = {
suppressScrollOnNewData: true,
rowSelection: 'single',
rowModelType: 'infinite',
deltaRowDataMode: true,
defaultColDef: {
sortable: false,
resizable: true
},
columnTypes: {
'imageColumn': {
width: 150,
sortable: false,
autoHeight: true,
cellRendererFramework: AgGridImageFormatter
},
'priceColumn': {
cellRendererFramework: AgGridPriceFormatter
}
}
};
Methods:
({
methods: {
onBodyScroll: function(event) {
var lastDisplayedWork, ref, worksCount;
worksCount = this.works.length;
lastDisplayedWork = (ref = this.gridOptions.api) != null ? ref.getLastDisplayedRow() : void 0;
if (worksCount - 2 < lastDisplayedWork) {
event.api.ensureIndexVisible(worksCount - 2);
this.loadMore();
return event.api.setDatasource(this.gridDatasource);
}
},
CreateAgGridDataSource: function(worksData) {
return {
rowCount: this.works.length,
getRows: (function(_this) {
return function(params) {
var lastRow, rowsThisPage;
rowsThisPage = _this.works.slice(params.startRow, params.endRow);
lastRow = -1;
return params.successCallback(rowsThisPage, lastRow);
};
})(this)
};
},
onRowSelected: function(event) {
return this.workClicked(event.data.id);
},
onGridReady: function(event) {
this.gridDatasource = this.CreateAgGridDataSource(this.works);
return event.api.setDatasource(this.gridDatasource);
}
}
});
Apologies for any weird JS code, I'm using a CoffeeScript to JS converter. I think it should be ok though.
HTML:
<div id="gridContainer">
<ag-grid-vue class="ag-theme-balham" id="AgGrid" :gridOptions="gridOptions" :modules="agGridModules" :columnDefs="agGridColDefs" @body-scroll="onBodyScroll" @row-selected="onRowSelected" @grid-ready="onGridReady"></ag-grid-vue>
</div>
How can I make sure that the scroll stays wherever the user has scrolled to? For the record, using api.refreshCells()
doesn't work. With that I get blank rows after the first data call (so only the first ~23 or so items display). So, I need to "refresh" the datasource each time new data is fetched.
- same problem here... – Giovanni Avila Commented Aug 27, 2020 at 8:02
3 Answers
Reset to default 3You need to implement the getRowId
callback, otherwise I guess the grid doesn't know which rows are actually new. See https://www.ag-grid./angular-data-grid/row-ids/#application-assigned-ids for explanation
This isn't going to be an appropriate answer for everyone but my pany went ahead and bought the Enterprise Ag-Grid. This gave me access to the Server Side Row Model, which in turn gives you the opportunity to only render certain rows. I can mimic server fetching inside the data source fetch, then only render the rows that were returned. This is adequate for us because we have the license - I don't think this sort of thing is possible with munity edition.
This works fine:
gridOptions.api.refreshInfiniteCache()