angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.37k stars 6.75k forks source link

[Table] Expose paginated data on MatTableDataSource #9419

Open oktav777 opened 6 years ago

oktav777 commented 6 years ago

Bug, feature request, or proposal:

feature request

What is the expected behavior?

MatTableDataSource should provide a method to get currently rendered data which is filtered, sorted and paginated.

What is the current behavior?

At the moment I couldn't find the right way to get rendered data(It may exist but it's not documented).

What are the steps to reproduce?

--

What is the use-case or motivation for changing an existing behavior?

I have found a hacky way to get currently rendered data on the table page. The data is filtered, sorted, and paginated, so I have to get the currently visible data, for let's say row selection's page toggle(clicking it will select all filtered and sorted data on the current table page).

I'm using this.dataSource['_renderData']['value'], but the problem is that, _renderData is a private property of type BehaviorSubject. So accessing data in this way doesn't look good.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

latest

Is there anything else we should know?

--

willshowell commented 6 years ago

A task-specific method would probably be better, but you should also be able to use dataSource.connect().value if you want to avoid private properties.

andrewseguin commented 6 years ago

From a UX perspective, I imagine that users who want to perform a "Select All" will want to have all the table's filtered data included, not just the data displayed on the current page. Are you sure your use case is that you only want to select the current page?

For now, you can subscribe directly to the data source's connect() function which will provide the renderData stream.

matTableDataSource.connect().subscribe(data => ...)

In the future, we may want to directly support virtualization so the rendered rows may be just a subset of the current page, and not what you want. In that case I think you'll want another property on the data source similar to filteredData but one that contains the paginated data.

oktav777 commented 6 years ago

@andrewseguin Let's take for example a table with 100 entries, the table is displaying 10 items per page, we also can filter the data in table and sort it.

The user is filtering somehow the data and gets 25 entries(3 pages), then the user is sorting data by a column and wants to modify somehow the first 10 entries(merge 10 values in one for example), so instead of checking by one 10 entries, there is a page toggle that selects only the current page(all 10 items), but there is also a master toggle that is selecting all filtered entries(sorting in this situation doesn't influence selection), which data is contained in filteredData. So I think it would be great to have a parameter that contains currently rendered data. I had a function that was returning the rendered data, but I thought there is already something build in, so I removed mine:

get renderedRows(): Array<T> {
    let startIndex: number = this.paginator.pageSize * this.paginator.pageIndex;
    let endIndex: number = this.paginator.pageSize + startIndex;

    let array: Array<T> = [];

    if(this.dataSource.filteredData.length) {
        array = this.dataSource.filteredData;
    } else {
        array = this.dataSource.data;
    }

    return array.slice(startIndex, endIndex);
}

and replaced with

dataSource.connect().value
chriszrc commented 4 years ago

I think the current support is fine:

matTableDataSource.connect().subscribe(data => ...)

But it's not really documented on this page:

https://material.angular.io/components/table/api

The connect method is mentioned briefly in the description for the @Input() dataSource, but it seems this method should have it's own documentation.

angular-robot[bot] commented 2 years ago

Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

Find more details about Angular's feature request process in our documentation.

angular-robot[bot] commented 2 years ago

Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

You can find more details about the feature request process in our documentation.