Столбец сортировки Angular mat-table, который отображается из функции

Каков правильный способ сортировки мат-таблицы, в которой есть один столбец, отображающий описание, а не код мат-выбора. Рассмотрим следующий пример кода, который представляет собой редактируемую таблицу матов, которая отображает описание выбранного элемента из столбца мат-выбор в режиме редактирования, когда он не в режиме редактирования. Это означает, что когда сетка не находится в режиме редактирования, я вызываю функцию, чтобы дать мне отображаемое описание.

В статическом режиме:

<div *ngIf = "col.key == 'MGA_ServiceDescription'">
    <span >
        {{ getServiceDescription(element[col.key]) }}
    </span>
</div>

В режиме редактирования:

mat-form-field *ngSwitchCase = "'listServiceDescriptions'" >
   <mat-select [(value)] = "element[col.key]">
       <mat-option *ngFor = "let c of filteredServices" [value] = "c.SDE_CODE"
           {{ c.SDE_DESCRIPTION}}
       </mat-option>
   </mat-select>
/mat-form-field>

Пример кода

у вас есть ссылка на stackblitz для этого?

Jimmy 27.11.2022 21:51

Нет, он тебе нужен?

Marc Roussel 28.11.2022 13:44

Вот стекблиц: stackblitz.com/edit/…

Marc Roussel 28.11.2022 16:07

Сортировка по роду занятий работает, я полагаю? Когда я редактирую его, новые занятия исчезают, в этом проблема?

Jimmy 28.11.2022 18:40

Проблема заключается не в редактировании, а в сортировке модели, связанной со списком занятий. Как видите, если сортировать по возрастанию, то B, B, A, A фактически соответствуют Y и Z коду выбора, к которому привязана модель. Я знаю, что редактирование не работает в этом блице, но проблема не в этом.

Marc Roussel 28.11.2022 20:16

то есть вы хотите, чтобы сортировка работала с Y/Z вместо A/B, но по-прежнему отображалась в пользовательском интерфейсе как A/B? Я знаю, что это не мое дело, но вы не думаете, что это немного смущает пользователей? они нажимают сортировку, а затем она отображается как A/B/A/A/B, что совсем не похоже на «сортировку».

Jimmy 28.11.2022 20:19

Нет, сортировка должна быть по тому, что показано визуально, поэтому A и B, а не Y и Z.

Marc Roussel 28.11.2022 22:08
Тестирование функциональных 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
0
7
331
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

sortingDataAccessor принимает текущую строку и атрибут сортировки. Поскольку вы работаете над «оккупацией», свойство = род занятий, элементы будут USER_DATA

sortingDataAccessor применяется ко всем столбцам, поэтому нам нужно проверить, интересующий нас столбец. Вот почему нам нужен переключатель/кейс.
В столбце «оккупация» у вас есть карта occupationsList, которая отображает X => A, Y => B, Z => C... Мы хотим, чтобы вместо сортировки по X/Y/Z она сортировалась по A/ B/C => вместо этого вернуть A/B/C, поэтому я возвращаю description (the mapped value)

this.dataSource = new MatTableDataSource(USER_DATA);
    this.dataSource.sortingDataAccessor = (item, property) => {
      switch(property) {
        case 'occupation': occupationsList.find(o => o.name === item.occupation).description;
        default: return item[property];
      }
    };
    this.dataSource.sort = this.sort;

Я скоро попробую

Marc Roussel 28.11.2022 22:09

На сегодняшний день безуспешно. Я правильно добавил код, и ошибок нет, но сортировка неправильная. Я собираюсь сделать второй блиц, чтобы лучше продемонстрировать проблему. Может быть, на кону что-то еще.

Marc Roussel 30.11.2022 19:17

Я изменил свой блиц, чтобы точно отразить мой исходный код с sortingDataAccessor на месте. Как видите, Служба по-прежнему сортируется по коду, а не по названию.

Marc Roussel 30.11.2022 20:01

SDE_CODE сортируется, а не SDE_DESCRIPTION, несмотря на правильность sortingDataAccessor (я думаю)

Marc Roussel 30.11.2022 20:08

ты не вернулся в случае с переключателем, чувак, попробуй еще раз

Jimmy 01.12.2022 14:18

Я думаю, что забыл о возврате, потому что в вашем примере его не было в случае переключения «занятие», возможно, для других было бы разумно отредактировать ваш ответ. спасибо

Marc Roussel 05.12.2022 02:00

«Лучший способ», когда у нас есть массив и одно свойство действительно является «выбором», — это добавить в массив «описание».

Представьте себе что-нибудь вроде

  ngOnInit() {
    this.dataSource = new MatTableDataSource(
      USER_DATA.map((code: any) => {
        const serviceDescription = this.serviceDescriptions.find(
          (desc: any) => desc.SDE_CODE === code.MGA_ServiceDescription
        );
        return {
          ...code,
          description: serviceDescription? serviceDescription.SDE_DESCRIPTION: '',
        };
      })
    );
  }

Ну, есть некоторые проблемы. Во-первых, изменить «sortHeader», мы это сделали, когда столбец был отсортирован «MGA_ServiceDescription» по новому свойству, поэтому:

<th
        mat-header-cell
        *matHeaderCellDef
        [mat-sort-header] = "col.key=='MGA_ServiceDescription'?'description':col.key"
        [disabled] = "col.key == 'isEdit'"
      >

Другая проблема заключается в том, как «редактировать» элемент. Если мы используем мат-выбор, мы можем выбрать, чтобы значение опций было «SDE_CODE» или собственное описание службы.

Я собираюсь выделить весь объект. Но для этого нам нужна функция compareWith

serviceCompareWith=(a:any, MGA_ServiceDescription:any)=>
                             a.SDE_CODE==MGA_ServiceDescription

И при изменении измените два свойства: «MGA_ServiceDescription» и «описание».

  change(value:any,element:any)
  {
    element.MGA_ServiceDescription=value.SDE_CODE;
    element.description=value.SDE_DESCRIPTION
  }

Теперь наш "mat-select" становится похожим на

<mat-select [compareWith] = "serviceCompareWith" 
            [value] = "element.MGA_ServiceDescription"  
            (selectionChange) = "change($event.value,element)">
        <mat-option *ngFor = "let service of serviceDescriptions" [value] = "service">
          {{service.SDE_DESCRIPTION}}
        </mat-option>
</mat-select>

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