Каков правильный способ сортировки мат-таблицы, в которой есть один столбец, отображающий описание, а не код мат-выбора. Рассмотрим следующий пример кода, который представляет собой редактируемую таблицу матов, которая отображает описание выбранного элемента из столбца мат-выбор в режиме редактирования, когда он не в режиме редактирования. Это означает, что когда сетка не находится в режиме редактирования, я вызываю функцию, чтобы дать мне отображаемое описание.
В статическом режиме:
<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.com/edit/…
Сортировка по роду занятий работает, я полагаю? Когда я редактирую его, новые занятия исчезают, в этом проблема?
Проблема заключается не в редактировании, а в сортировке модели, связанной со списком занятий. Как видите, если сортировать по возрастанию, то B, B, A, A фактически соответствуют Y и Z коду выбора, к которому привязана модель. Я знаю, что редактирование не работает в этом блице, но проблема не в этом.
то есть вы хотите, чтобы сортировка работала с Y/Z вместо A/B, но по-прежнему отображалась в пользовательском интерфейсе как A/B? Я знаю, что это не мое дело, но вы не думаете, что это немного смущает пользователей? они нажимают сортировку, а затем она отображается как A/B/A/A/B, что совсем не похоже на «сортировку».
Нет, сортировка должна быть по тому, что показано визуально, поэтому A и B, а не Y и Z.
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;
Я скоро попробую
На сегодняшний день безуспешно. Я правильно добавил код, и ошибок нет, но сортировка неправильная. Я собираюсь сделать второй блиц, чтобы лучше продемонстрировать проблему. Может быть, на кону что-то еще.
Я изменил свой блиц, чтобы точно отразить мой исходный код с sortingDataAccessor на месте. Как видите, Служба по-прежнему сортируется по коду, а не по названию.
SDE_CODE сортируется, а не SDE_DESCRIPTION, несмотря на правильность sortingDataAccessor (я думаю)
ты не вернулся в случае с переключателем, чувак, попробуй еще раз
Я думаю, что забыл о возврате, потому что в вашем примере его не было в случае переключения «занятие», возможно, для других было бы разумно отредактировать ваш ответ. спасибо
«Лучший способ», когда у нас есть массив и одно свойство действительно является «выбором», — это добавить в массив «описание».
Представьте себе что-нибудь вроде
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>
у вас есть ссылка на stackblitz для этого?