angular / angular/components

feat(MatTable) Add `sortPredicate` to MatTableDataSource or MatSort

Offen
#24,926 0 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen
area: material/sort area: material/table feature P4
Vorherrschende Sprache
TypeScript
Sterne
25k
Forks
6.8k
Ø Merge
1 T. 8 Std.
Gemergte PRs (30 T.)
91

Beschreibung

### Feature Description

`MatTableDataSource` already has a `filterPredicate` property that allows you to pass a function with the signature `(data: T, filter: string) => boolean` to implement a custom filtering algorithm. This makes it much easier to control the behavior of the table when passing a filter value to the data source.
The same thing is not possible when sorting: currently, the only way to control the behavior of a `MatSort` on a `MatTableDataSource` is to set its `sortingDataAccessor` property. And this is extremely limited because it only allows to control what the sorting algorithm "sees" and not how it sorts the data.

Proposition:
Add a `sortPredicate` analogous to `MatTableDataSource.filterPredicate` to either `MatTableDataSource` or `MatSort`.

This property would accept a function with the signature `(a: T, b: T, sort: Sort) => number` to mirror the signature of the comparison function passed to `Array.sort`.
An alternative would be a signature like `(sort: Sort) => (a: T, b: T) => number` which would return a comparison function derived the current sorting key/order.

Note that it would be better to be able to override the sort comparison function of only certain columns, in this case a possible solution would be to accept a function with the signature `(sort: Sort) => ((a: T, b: T) => number) | undefined` and fallback to the default comparison function on `undefined`.

This property would give a lot more control over the sorting algorithm to the user than what is currently possible.

### Use Case

There is no easy way to customize the sorting algorithm, for ex: https://stackoverflow.com/q/55016642/10061195
This property would also make it easier to sort nested objects. Currently, this needs to either give a specific name to the column to sort, or to catch the data access using `sortingDataAccessor`.

For example, a solution to the given SO question using the proposed property would be:
```ts
dataSource.sortPredicate = (sort: Sort) => {
if (sort.active === 'code') {
if (sort.direction === 'asc') {
return (a, b) => a.localeCompare(b, undefined, { numeric: true });
} else {
return (a, b) => b.localeCompare(a, undefined, { numeric: true });
}
}
};
```
or
```ts
// JS/TS does not support array as keys in object / Map
const compare = {
'code#asc': (a, b) => a.localeCompare(b, undefined, { numeric: true }),
'code#desc': (a, b) => b.localeCompare(a, undefined, { numeric: true }),
};

dataSource.sortPredicate = (sort: Sort) => compare[sort.active + '#' + sort.direction];
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne bei MatTableDataSource und MatSort und vergleiche das bestehende Verhalten von filterPredicate und sortingDataAccessor. Überprüfe die vorgeschlagenen Comparator-Signaturen und den spaltenspezifischen Fallback, bevor du dich für eine API-Form entscheidest. Erledigt ist die Aufgabe, wenn benutzerdefiniertes Sortieren angewendet werden kann und die bestehende Standardsortierung weiterhin verfügbar ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
angular, typescript
Bereich
frontend
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.