首页 > 解决方案 > Angular Material2 Mat-Table Server Side Pagination Cross Page Row Selection

问题描述

How do I implement cross page row selection on Angular Material 2 mat-table when using server side pagination?

I have a working Angular Material table with server side pagination. However, the default implementation (as documented in the Material docs) unchecks all rows (and the "select all rows" checkbox) when navigating to a new page.

I've tried a huge variety of things/approaches (too many to document here) but here are some snippets that might be helpful. Code has been simplified for clarity.

The selections.selected array does contain all selected rows across pages. By changing the default isSelected function to a custom function -- rows across pages display as selected. Note that in my case rows have a unique property _id.

private isSelectedCustom(row: any): boolean {
    return <boolean>this.selection.selected.find(o => o._id === row._id);
}

selection.isSelected = isSelectedCustom.bind(this);

However, if I uncheck a row (navigate to a new page and come back) the row shows as checked again. It's unclear why and I've even seen duplicate rows in selection.selected when unchecking rows and navigating between pages.

Trying to manually remove rows (and duplicate rows) from selection did not work i.e.

selection.onChange.subscribe(selection => {

    if (selection && selection.removed && selection.removed[0] && selection.removed.length == 1) {

        let removeId = selection.removed[0]._id;

        // Remove multiple occurences. Unknown how selection.selected can have duplicates.
        for (var i = this.selection.selected.length - 1; i >= 0; i--) {

            if (this.selection.selected[i]['_id'] == removeId) {
                console.log('force remove', this.selection.selected[i]);
                //this.selection.selected.splice(i, 1);
                this.selection.selected.
            }
        }
    }
}

For the "select all rows" checkbox it's not possible to derive if all rows are selected (because the client only has a page of rows not all rows). So I use a flag which is explicitly set to true/false when "select all rows" is checked/unchecked.

When navigating to subsequent pages, if the "select all rows" flag is true then I set all rows to checked.

dataSource.data.forEach(row => selection.select(row));

If a row is unchecked I set the "select all rows" flag to false.

if (selection && selection.removed && selection.removed.length > 0) {
    isAllPagesSelected = false;
}

This "select all rows" checkbox approach seems to generally work but feels messy.

标签: angular-material2

解决方案


如果没有跨页,它会容易得多,但是

onPageChanged -> 加载新数据 -> 删除所有检查 -> 从 viewChild-> foreach 查找行 -> 为每一行设置检查/取消检查(包括标题中的 checkAllbox)。

可能需要 viewChild forEach row => 找到最近的复选框并 setChecked


推荐阅读