我正在使用SlickGrid的分页版本和CheckboxSelection-Plugin。不幸的是,当一个人离开当前网格页面时行选择会丢失,而当再次访问该页面时不会恢复。也可以使用SlickGrid example #4重现此行为。 (单击网格页脚中的小灯泡图标以打开分页)
我已经通知了SlickGrid的作者,但他没有将这种行为视为一个错误,因为SlickGrid更像是一个网格框架,而不仅仅是一个添加数据解决方案。
有没有人知道如何在SlickGrid中实现可靠的选择持久性,这适用于分页和非分页网格?
答案 0 :(得分:2)
最后,我通过在示例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
}
}
});
数组,然后迭代它以检查是否已取消选择其当前页面条目之一。
{{1}}
答案 1 :(得分:0)
提案:
在网格定义之前添加行数组。
var selectedRows = [];
在pagging事件中,如果行尚未在数组中,则在获取并存储所选行之前:
function AddRows(grid.getSelectedRows()){//your comparision here};
在paggin事件中设置选定的行:
grid.setSelectedRows(selectedRows );
防止取消选择。如果取消选择行,则获取数组中的行索引,并从数组中删除该行:
function GetRowSelectedIndex(row);
var rowIndex = GetRowSelectedIndex(row);
selectedRows.slice(rowIndex,1);
答案 2 :(得分:0)
它工作正常。刚刚修改了上面一个。
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; });
}
}
答案 3 :(得分:0)
我知道这是一个老问题,但是我必须实现它,并且提议的解决方案不能涵盖所有用例(例如,如果用户转到最后一页,则@fbuchinger提出的解决方案将删除一些选择,而不进行任何操作)选择,然后返回首页)。
为解决此问题,我不得不做一个更复杂的实现,甚至必须添加一个新的DataView事件onBeforePagingInfoChanged
,还修改了SlickGrid事件onSelectedRowsChanged
以也返回以前的行选择(在当前选择的顶部)。这些更改是在6pac/SlickGrid分支中进行的,并在版本2.4.18
下发布了
使用分页时,我使用的步骤如下,我们不能仅使用getSelectedRows()
,因为这只会返回当前页面中的选择,这是不够的,我们需要保留一个包含数据的全局数组对象ID(不是行索引,因为它会在页面中不断变化),为保持网格索引和数据ID,我们将在dataView.mapIdsToRows()
和dataView.mapRowsToIds()
之间进行切换。
下面显示的代码步骤如下
// 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 };
}
});
}
因此在此代码中,变量this._selectedRowDataContextIds
具有所选数据对象ID的完整集合。这是一种复杂的方法,但是到目前为止,我发现这是使用网格分页进行的。
请注意,在代码中只有1个lodash
函数isequal
用于比较2个数组,其他所有内容都是用ES6和TypeScript编写的(尽管我删除了这些类型以提高可读性)< / p>