Алфавитно-цифровая сортировка таблицы материалов Angular

У меня проблема с 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>

Есть ли способ сделать это?

Связанная ссылка:

Естественная сортировка

Столбец сортировки, содержащий как числа, так и строки

вам следует реализовать пользовательскую сортировку в вашем источнике данных (sortingDataAccessor). для естественного порядка вам может потребоваться реализовать собственный алгоритм.

jcuypers 06.03.2019 09:20
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
8
1
3 057
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете сделать что-то вроде этого.

var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['F1',
'F10',
'F2',
'F5',
'F9'];
console.info(myArray.sort(collator.compare));

ВОТ ЭТО ДА. Отличный ответ. Спасибо

RamAnji 27.02.2020 10:27

Вы можете добиться этого, добавив функцию сортировки после получения данных.

Применение:

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

Другие вопросы по теме