feat(MatTable) Add `sortPredicate` to MatTableDataSource or MatSort
- Langage dominant
- TypeScript
- Étoiles
- 25k
- Forks
- 6.8k
- Merge moyen
- 1 j 8 h
- PR mergées (30 j)
- 91
Description
### 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];
```
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par MatTableDataSource et MatSort, en comparant le comportement existant de filterPredicate et de sortingDataAccessor. Examinez les signatures de comparator proposées et le fallback spécifique à la colonne avant de choisir une forme d’API. La tâche est terminée lorsque le tri personnalisé peut être appliqué tout en conservant le tri par défaut existant.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- angular, typescript
- Domaine
- frontend
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100