angular / angular/components

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

Aperta
#24,926 0 commenti 1 reazione 0 assegnatari Vedi su GitHub
area: material/sort area: material/table feature P4
Lingua principale
TypeScript
Stelle
25k
Fork
6.8k
Merge medio
1g 8h
PR unite (30g)
91

Descrizione

### 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];
```

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da MatTableDataSource e MatSort, confrontando il comportamento esistente di filterPredicate e sortingDataAccessor. Esamina le firme di comparator proposte e il fallback specifico per colonna prima di scegliere una forma dell’API. Il lavoro è completato quando è possibile applicare un ordinamento personalizzato mantenendo disponibile l’ordinamento predefinito esistente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
angular, typescript
Ambito
frontend
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.