Jquery SlickGrid:如何在分页网格中保留选定行?

Jquery SlickGrid:如何在分页网格中保留选定行?,jquery,selection,slickgrid,Jquery,Selection,Slickgrid,我正在使用分页版本的SlickGrid和CheckboxSelection插件。不幸的是,当一个人离开当前的网格页面时,行选择会丢失,并且在再次访问该页面时不会恢复。这种行为也可以通过复制。(单击网格页脚中的小灯泡图标以启用分页) 我已经将这一点告知了SlickGrid的作者,但他并不认为这是一个bug,因为SlickGrid更像是一个网格框架,而不仅仅是一个添加数据的解决方案 有人知道如何在SlickGrid中实现可靠的选择持久性吗?它适用于分页网格和非分页网格 提案: 在网格定义之前添加行数

我正在使用分页版本的SlickGrid和CheckboxSelection插件。不幸的是,当一个人离开当前的网格页面时,行选择会丢失,并且在再次访问该页面时不会恢复。这种行为也可以通过复制。(单击网格页脚中的小灯泡图标以启用分页)

我已经将这一点告知了SlickGrid的作者,但他并不认为这是一个bug,因为SlickGrid更像是一个网格框架,而不仅仅是一个添加数据的解决方案

有人知道如何在SlickGrid中实现可靠的选择持久性吗?它适用于分页网格和非分页网格

提案:

  • 在网格定义之前添加行数组

    var selectedRows = [];
    
  • 在分页事件中,如果行尚未在数组中,则在获取并存储所有选定行之前:

    function AddRows(grid.getSelectedRows()){//your comparision here};
    
  • 在paggin事件集中选定的行:

    grid.setSelectedRows(selectedRows ); 
    
  • 防止取消选择。如果取消选择一行,则获取数组中的行索引,并从数组中删除该行:

    function GetRowSelectedIndex(row);
    var rowIndex = GetRowSelectedIndex(row);
    selectedRows.slice(rowIndex,1);
    

  • 最后,通过调整示例4中的grid.onSelectedRowsChanged回调,我取得了一些成功。关键区别在于,我不会在每次选择更改时重置全局
    selectedRowIds
    数组,因为
    grid.getSelectedRows()
    只提供当前页面上选定的行索引。相反,我首先将所有新选择的行添加到
    selectedRowIds
    数组中,然后对其进行迭代以检查其当前页面条目中是否有一个已被取消选择

    grid.onSelectedRowsChanged.subscribe(function (e) {
        var selRows = grid.getSelectedRows();
        // add all newly selected rows to the selection
        for (var i = 0, l = selRows.length; i < l; i++) {
            var item = dataView.getItem(selRows[i]);
            if (item) {
                var rowId = item.id;
                if (selectedRowIds.indexOf(rowId) < 0) {
                    selectedRowIds.push(rowId);
                }
            }
        }
    
        //check if a previously selected row has been deselected
        for (var i = 0, l = selectedRowIds.length; i < l; i++) {
            var row = dataView.getRowById(selectedRowIds[i]); // see if the selected row is   available on the current page
            if (row && selRows.indexOf(row) < 0) {
                selectedRowIds.splice(i, 1); //remove row from array
            }
        }
       });
    
    grid.onSelectedRowsChanged.subscribe(函数(e){
    var selRows=grid.getSelectedRows();
    //将所有新选择的行添加到选择中
    对于(变量i=0,l=selRows.length;i
    它工作正常。只是修改了上面的一个

                    var selRows = grid.getSelectedRows();
                    var item = {};
                    for (var i = 0; i < selRows.length; i++) {
                        item = dataView.getItem(selRows[i]);
                        if (item != undefined && $.inArray(item.id, selectedRowIds) < 0 ) {
                            selectedRowIds.push(item.id);
                        }
                    }
                    var removeIds = [];
                    var row;
                    for (var i = 0; i < selectedRowIds.length; i++) {
                        for (var j = 0; j < selectedRowIds.length; j++) {
                            row = dataView.getRowById(selectedRowIds[j]);
                            if(row != undefined && $.inArray(row, removeIds) < 0){
                                removeIds.push(row);
                                break;
                            }
                        }
                    }
                    for (var i = 0; i < removeIds.length; i++) {
                        if (removeIds[i] != undefined && $.inArray(removeIds[i], selRows) < 0) {
                            item = dataView.getItem(removeIds[i]);
                            selectedRowIds = $.grep(selectedRowIds, function( a ) { return a !== item.id; });
                        }
                    }
    
    var selRows=grid.getSelectedRows();
    var item={};
    对于(变量i=0;i
    我知道这是一个老问题,但我必须实现这一点,建议的解决方案并没有涵盖所有用例(例如,@fbuchinger建议的解决方案在用户转到最后一页时删除了一些选择,而没有做任何选择,并返回到第一页)

    为了解决这个问题,我必须做一个更复杂的实现,我甚至必须在PagingFoChanged之前添加一个新的DataView事件
    ,还修改了SlickGrid事件
    onSelectedRowsChanged
    ,以返回以前的行选择(在当前选择之上)。这些更改是在fork中进行的,并在版本
    2.4.18

    使用分页时,我使用的步骤如下所示,我们不能只使用
    getSelectedRows()
    ,因为这只会返回当前页面中的选择,这是不够的,我们需要保留一个带有数据对象ID的全局数组(而不是行索引,因为它会在页面中不断变化),为了保留网格索引和数据ID,我们将在
    dataView.mapIdsToRows()
    dataView.mapRowsToIds()之间交替使用

    下面显示的代码步骤如下所示

  • 当更改行选择时,如果新选择尚未在选定ID的全局数组中,我们将添加它
  • 删除行选择时,我们将从所选ID的全局数组中删除该选择(除非它来自页面更改)
  • 在我们更改页面之前,我们将使用一个标志进行跟踪(当我们更改页面时,该标志将用于跳过任何删除)
  • 页面更改后,我们将进行额外(延迟)检查,以确保在屏幕上显示所选ID的全局数组中的内容
  • //全局变量
    _SelectedRowDataContextId=[];//用于行选择
    _WasRechedAfterPageChange=true;//用于行选择和分页
    函数BindSlickGridEventsErrorSelectionWithPagination(){
    this.\u eventHandler.subscribe(this.\u dataView.onBeforePagingFoChanged,()=>{
    此.\u wasrecedafterpagechange=false;//重置页面检查标志,以跳过页面更改时的删除(在下面的代码中使用)
    });
    this.\u eventHandler.subscribe(this.\u dataView.onpagingfochanged,()=>{
    
    // global variables
    _selectedRowDataContextIds = [];     // used with row selection
    _wasRecheckedAfterPageChange = true; // used with row selection & pagination
    
    function bindSlickgridEventsForRowSelectionWithPagination() {
    this._eventHandler.subscribe(this._dataView.onBeforePagingInfoChanged, () => {
            this._wasRecheckedAfterPageChange = false; // reset the page check flag, to skip deletions on page change (used in code below)
          });
    
          this._eventHandler.subscribe(this._dataView.onPagingInfoChanged, () => {
            // when user changes page, the selected row indexes might not show up
            // we can check to make sure it is but it has to be in a delay so it happens after the first "onSelectedRowsChanged" is triggered
            setTimeout(() => {
              const shouldBeSelectedRowIndexes = this._dataView.mapIdsToRows(this._selectedRowDataContextIds);
              const currentSelectedRowIndexes = this._grid.getSelectedRows();
              if (!isequal(shouldBeSelectedRowIndexes, currentSelectedRowIndexes)) {
                this._grid.setSelectedRows(shouldBeSelectedRowIndexes);
              }
            });
          });
    
          this._eventHandler.subscribe(this._grid.onSelectedRowsChanged, (e, args) => {
            if (Array.isArray(args.rows) && Array.isArray(args.previousSelectedRows)) {
              const newSelectedRows = args.rows;
              const prevSelectedRows = args.previousSelectedRows;
    
              const newSelectAdditions = newSelectedRows.filter((i) => prevSelectedRows.indexOf(i) < 0);
              const newSelectDeletions = prevSelectedRows.filter((i) => newSelectedRows.indexOf(i) < 0);
    
              // deletion might happen when user is changing page, if that is the case then skip the deletion since it's only a visual deletion
              // if it's not a page change (when the flag is true), then proceed with the deletion in our global array of selected IDs
              if (this._wasRecheckedAfterPageChange && newSelectDeletions.length > 0) {
                const toDeleteDataIds = this._dataView.mapRowsToIds(newSelectDeletions);
                toDeleteDataIds.forEach((removeId) => this._selectedRowDataContextIds.splice(this._selectedRowDataContextIds.indexOf(removeId), 1));
              }
    
              // if we have newly added selected row(s), let's update our global array of selected IDs
              if (newSelectAdditions.length > 0) {
                const toAddDataIds = this._dataView.mapRowsToIds(newSelectAdditions) || [];
                toAddDataIds.forEach((dataId) => {
                  if (this._selectedRowDataContextIds.indexOf(dataId) === -1) {
                    this._selectedRowDataContextIds.push(dataId);
                  }
                });
              }
              this._wasRecheckedAfterPageChange = true;
    
              // form our full selected row IDs, let's make sure these indexes are selected in the grid, if not then let's call a reselect
              // this could happen if the previous step was a page change
              const shouldBeSelectedRowIndexes = this._dataView.mapIdsToRows(this._selectedRowDataContextIds);
              const currentSelectedRowIndexes = this._grid.getSelectedRows();
              if (!isequal(shouldBeSelectedRowIndexes, currentSelectedRowIndexes)) {
                this._grid.setSelectedRows(shouldBeSelectedRowIndexes);
              }
    
    
              const newSelections = { gridRowIndexes: this._grid.getSelectedRows(), dataContextIds: this._selectedRowDataContextIds };
            }
          });
    }