#javascript #angular
#javascript #angular
Вопрос:
Я создаю пользовательский метод сортировки в Angular, который принимает в качестве параметра имя типа string . В файле .html всякий раз, когда пользователь нажимает на стрелки, скажем, например, рядом с «UserName», имя пользователя передается в качестве аргумента моему методу сортировки. Я хочу, чтобы мой метод не учитывал регистр и, похоже, не может найти способ доступа и изменения массива значений ключей объектов. Используя приведенный выше пример «UserName», я хочу получить доступ к имени ключа объекта «UserName» и сделать значение строчным перед сортировкой. Таким образом, мой метод сортировки будет работать правильно. Имейте в виду, что мои данные находятся внутри массива, который содержит объекты пользовательской информации. Я также использую обозначение в скобках, чтобы сохранить его динамичным; например, в моем методе вы увидите [name] <b[name], где [name] равно тому, на что нажимает пользователь.
Мой ФАЙЛ .TS
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent extends ComponentCanDeactivate implements OnDestroy {
entries: User[] = []; isAscendingOrder=false; isFaSort=true; sortByParam='';
faEdit=faEdit; faTrash=faTrash; faCaretSquareDown=faCaretSquareDown; faCaretSquareUp=faCaretSquareUp; faSort=faSort;
@ViewChild('addUserForm') formValues;
constructor(private userService: UserService, private globals: GlobalsService, private modalService: NgbModal) {
super(); this.load();
}
ngOnDestroy() { try { this.modalService.dismissAll(); } catch(err) { console.log(err); } }
canDeactivate(): boolean { return !this.modalService.hasOpenModals();}
load(){
this.userService.getAllUsers(r => {
if (r) {
this.entries = r; this.getValues(this.entries)
} else {
this.globals.toastr.error('Error getting users');
}
});
}
switchIcon() {
if(this.isFaSort) {
return faSort;
} else {
return this.isAscendingOrder? faCaretSquareUp:faCaretSquareDown;
}
}
getValues(userArray: User[]) {
userArray.forEach(e=> {
const result = Object.entries(e).map(([k,v]) => {
e.UserName = v.toLowerCase();
})
console.log(result);
});
}
sortByField(name:string) {
this.isFaSort = false;
if(this.sortByParam == name) {
this.isAscendingOrder= !this.isAscendingOrder;
} else {
this.sortByParam = name;
this.isAscendingOrder = true;
}
if(this.isAscendingOrder) {
return this.entries.sort((a, b) => {
if (a[name] < b[name])
return -1;
if (a[name] > b[name])
return 1;
return 0;
});
} else {
return this.entries.sort((a, b) => {
if (a[name] < b[name])
return 1;
if (a[name] > b[name])
return -1;
return 0;
});
}
}
Вы можете видеть в моем файле .ts, что я пытаюсь найти способ изменить значение ключа объекта.
.HTML-файл
<div class="table-overflow-container">
<table class='table table-bordered table-fixed-header table-striped table-narrow table-hover'>
<thead class="my-thead">
<tr>
<td class="clickable" (click)="sortByField('UserName')">User name<fa-icon style="float: right;" [icon]="switchIcon()">
</fa-icon>
</td>
<td class="clickable" (click)="sortByField('Email')">Email<fa-icon style="float: right;" [icon]="switchIcon()">
</fa-icon></td>
<td>Roles</td>
<td class="clickable">Disabled<fa-icon style="float: right;" [icon]="switchIcon()">
</fa-icon></td>
</tr>
</thead>
<tbody>
<tr *ngFor="let u of entries">
<td class="clickable" (click)="editUser(u.id)">{{u.UserName}}</td>
<td class="clickable" (click)="editUser(u.id)">{{u.Email}}</td>
<td class="clickable" (click)="editUser(u.id)">{{ getRoleNames(u.UserRoles) }}</td>
<td class="clickable" (click)="editUser(u.id)">{{u.Disabled==0?"No":"Yes"}}</td>
</tr>
</tbody>
</table>
Ответ №1:
Вы можете сделать его немного более организованным, например, так:
sortByField(name:string) {
this.isFaSort = false;
if(this.sortByParam == name) {
this.isAscendingOrder= !this.isAscendingOrder;
} else {
this.sortByParam = name;
this.isAscendingOrder = true;
}
function getLowerCaseEntry(a, b) {
return a[b].toLowerCase();
}
function compareStr(a ,b, asc) {
return asc ? a.localeCompare(b) : b.localeCompare(a);
}
this.entries.sort((x,y) => compareStr(getLowerCaseEntry(x, name), getLowerCaseEntry(y, name), this.isAscendingOrder));
}
Ответ №2:
Просто добавьте модификатор toLowerCase() . если [name] может быть чем-то не строковым, то [name].toString().toLowerCase()
if(this.isAscendingOrder) {
return this.entries.sort((a, b) => {
if (a[name].toLowerCase() < b[name].toLowerCase())
return -1;
if (a[name].toLowerCase() > b[name].toLowerCase())
return 1;
return 0;
});
} else {
return this.entries.sort((a, b) => {
if (a[name].toLowerCase() < b[name].toLowerCase())
return 1;
if (a[name].toLowerCase() > b[name].toLowerCase())
return -1;
return 0;
});
}
Комментарии:
1. вау.. Я был почти уверен, что добавлял метод toLowerCase, и он постоянно говорил мне, что не может .. но, черт возьми, теперь это работает! Это то, что я искал, основываясь на моем коде, поэтому будет принятым ответом, хотя мне нравится подход, предложенный выше, чтобы лучше организовать мой код.