У меня проблема с Angular Material Table, хотя технически это правильно, но я думаю, есть ли для этого другой способ.
Допустим, у меня есть 5 кодов, F1, F2, F5, F9, F10.
Порядок сортировки по возрастанию таблицы материалов Angular будет следующим:
F1
F10
F2
F5
F9
Но я ожидаю, что это будет
F1
F2
F5
F9
F10
Мой html-код здесь
<table mat-table [dataSource] = "model.financingPurposeList" class = "mat-elevation-z8" width = "100%">
<ng-container matColumnDef = "code">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Code </th>
<td mat-cell *matCellDef = "let financingPurpose"> {{financingPurpose.code}} </td>
</ng-container>
<ng-container matColumnDef = "description">
<th mat-header-cell *matHeaderCellDef> Description </th>
<td mat-cell *matCellDef = "let financingPurpose"> {{financingPurpose.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef = "['code', 'description']; sticky: true"></tr>
<tr mat-row *matRowDef = "let row; columns: ['code', 'description'];" (click) = "model.selectedFinancingPurpose.toggle(row)"></tr>
</table>
Есть ли способ сделать это?
Связанная ссылка:





Вы можете сделать что-то вроде этого.
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['F1',
'F10',
'F2',
'F5',
'F9'];
console.info(myArray.sort(collator.compare));ВОТ ЭТО ДА. Отличный ответ. Спасибо
Вы можете добиться этого, добавив функцию сортировки после получения данных.
Применение:
ngOnInit() {
this.dataSource.data.sort((a, b) => (a.code- b.code) );
}
Это не лучшее решение для этого, но я создал для этого короткий и приятный обходной путь. Используя функцию предиката sort для array.
// Following the example to the question
financingPurposeList.sort(function(a, b){
return a.code.length - b.code.length;
});
В итоге я переопределил функцию сортировки в источнике данных, чтобы использовать локальное сравнение двух строк. Исходный код находится здесь https://github.com/angular/components/blob/master/src/material/table/table-data-source.ts#L165, а соответствующие строки, которые я изменил, приведены ниже.
this.dataSource.sortData = (data: T[], sort: MatSort) => {
.
.
.
let comparatorResult = 0;
if (valueA != null && valueB != null) {
// ----- Added this IF below ----.
if (valueAType === 'string' && valueBType === 'string') {
comparatorResult = (valueA as string).localeCompare(valueB as string, 'en', { numeric: true })
} else if (valueA > valueB) {
comparatorResult = 1;
} else if (valueA < valueB) {
comparatorResult = -1;
}
} else if (valueA != null) {
.
.
.
});
}
Прежде всего поместите прослушиватель событий matSortChange, который указывает на ваш метод сортировки, в тег таблицы HTML. В этом случае это sortData($event), но имя зависит от вас.
<table mat-table matSort aria-label = "Elements" [dataSource] = "dataSource" (matSortChange) = "sortData($event)">
Затем в коде компонента добавьте метод сортировки. Обратите внимание, что вам нужно вставить имя каждого столбца в оператор switch, по которому вы хотите выполнить сортировку.
sortData(sort: Sort): number {
const data = this.inputData.slice();
if (!sort.active || sort.direction === '') {
this.sortedData = data;
return;
}
const sortedData = this.inputData.slice(); // input data is your data.
sortedData.sort((a, b) => {
const isAsc = sort.direction === 'asc'; // detect sort direction
switch (sort.active) {
case 'name': return this.sortAlphanumeric(a.name, b.name, isAsc); // column name
default: return 0;
}
});
this.dataSource.data = sortedData; // assigns sorted data to your data in the table }
Следующим шагом является добавление пользовательского алгоритма естественной сортировки.
sortAlphanumeric(a: string, b: string, isAsc: boolean): number {
return isAsc ? a.localeCompare(b, 'en', { numeric: true }) : b.localeCompare(a, 'en', { numeric: true }); }
Аналогичное решение с базовым алгоритмом сортировки: https://material.angular.io/components/sort/overview
вам следует реализовать пользовательскую сортировку в вашем источнике данных (sortingDataAccessor). для естественного порядка вам может потребоваться реализовать собственный алгоритм.