最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ag-Grid resets scroll on new datasource - Stack Overflow

programmeradmin6浏览0评论

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.

Share Improve this question asked Dec 16, 2019 at 15:59 DanDan 3814 silver badges20 bronze badges 1
  • same problem here... – Giovanni Avila Commented Aug 27, 2020 at 8:02
Add a ment  | 

3 Answers 3

Reset to default 3

You 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()
发布评论

评论列表(0)

  1. 暂无评论