feat(MatTable) Add `sortPredicate` to MatTableDataSource or MatSort
- 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