Сортировка в таблице(angular)
Eсть таблица, при клике на его header-ы(name, surname, age или gender) нужно отсортировать по нажатым названиям, на пример если нажать по name, surname нужно будет отсортировать по алфавитному порядку, а по age возростанию
filtername(name) {
let frname = this.service.people.map(itm => itm['name'].first)
frname.sort()
}
filtersurname(surname) {}
filterage(age) {
// return age.map(itm=>itm.dob.age).sort((a,b)=>a-b)
}
filtergender(gender) {}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<table class="table table-bordered table-dark">
<tr>
<th (click)="filtername(service.people)">Name</th>
<th (click)="filtersurname(service.people)">Surname</th>
<th (click)="filterage(service.people)">Age</th>
<th (click)="filtergender(service.people)">Gender</th>
<th>Photo</th>
</tr>
<tr *ngFor="let item of service.people | filters:gender">
<td>{{item.name.first}}</td>
<td>{{item.name.last}}</td>
<td>{{item.dob.age}} </td>
<td>{{item.gender}} </td>
<td>
<img src="{{item.picture.large}}" alt="">
</td>
</tr>
</table>
в консоле всё нормально сортируется, но не получается реализовать в таблице
база людей взята из https://randomuser.me/api?results=20
исходники тут https://stackblitz.com/edit/angular-rkpnyt
Ответы (2 шт):
Немного модифицировал ваш код
Посмотрите пример https://stackblitz.com/edit/angular-og2vvk
Основные моменты:
app.component.ts
export class AppComponent {
gender: string = "all";
people = [];
filteredPeople = [];
constructor(public service: DataService) {
service.getPeoples().then(res => {
this.people = this.filteredPeople = res.results;
});
}
public sort(property: string): void {
this.filteredPeople = this.people.sort((a, b) =>
getDescendantProp(a, property) > getDescendantProp(b, property) ? 1 : -1
);
}
}
data.service.ts
export class DataService {
constructor(private http:HttpClient) {
}
public async getPeoples(): Promise<Tvyalner>{
return this.http.get<Tvyalner>("https://randomuser.me/api?results=20").toPromise();
}
}
В твоем примере ты сортируешь новый массив и никак его не используешь.
Директива *ngFor итерирует service.people. В момент сортировки ты создаешь новый массив frname. Никуда его не возвращаешь. После завершения функции результат сортировки просто уничтожается. По идее, тебе надо завести в компоненте переменную, содержащую копию исходного массива и все фильтрации и сортировки выполнять на ней.
К тому же, в темплейте ты во все сортировочные функции передаешь service.people. Я так понял, что это артефакты от твоих проб и ошибок. Но по сути это действие бесполезно, ведь весь сервис тебе доступен в .ts файле и обратно из темплейта его передавать нет необходимости.
Во время сортировки текста важно помнить о том, заглавные или строчные буквы используются. Текст при сравнении посимвольно конвертируется в число, эквивалентное позиции в таблице ASCII. Поэтому а и А это разные символьные значения. Cлова, начинающиеся на Б будут идти раньше, чем слова на а. Это стоит учитывать в алгоритме сортировки. Простой путь - это проверить, что ты сравниваешь, и если это строки, то привести обе строки либо к UpperCase либо к LowerCase.
if (typeof aPropValue === 'string') {
return aPropValue.toLowerCase() <= bPropValue.toLowerCase() ? -1 : 1;
} else {
return aPropValue <= bPropValue ? -1 : 1;
}
Чуть усовершенствованный вариант с сортировкой в обе стороны: