可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have problems with sorting an array of object in Angular2.
The object looks like:
[
{
"name": "t10",
"ts": 1476778297100,
"value": "32.339264",
"xid": "DP_049908"
},
{
"name": "t17",
"ts": 1476778341100,
"value": "true",
"xid": "DP_693259"
},
{
"name": "t16",
"ts": 1476778341100,
"value": "true",
"xid": "DP_891890"
}
]
And is being stored inside the values
variable.
All I want is to make the *ngFor
loop sort it by the name
property.
<table *ngIf="values.length">
<tr *ngFor="let elem of values">
<td>{{ elem.name }}</td>
<td>{{ elem.ts }}</td>
<td>{{ elem.value }}</td>
</tr>
</table>
Tried to do it with pipes, but failed miserably.
Any help appreciated.
Plunker link: https://plnkr.co/edit/e9laTBnqJKb8VzhHEBmn?p=preview
Edit
My pipe:
import {Component, Inject, OnInit, Pipe, PipeTransform} from '@angular/core';
@Component({
selector: 'watchlist',
templateUrl: './watchlist.component.html',
styleUrls: ['./watchlist.component.css'],
pipes: [ ArraySortPipe ]
})
@Pipe({
name: "sort"
})
export class ArraySortPipe implements PipeTransform {
transform(array: Array<string>, args: string): Array<string> {
array.sort((a: any, b: any) => {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
return array;
}
}
And just put the pipe
name into html file:
<tr *ngFor="let elem of values | sort">
回答1:
Although you can solve this problem with a pipe, you have to ask yourself if the re-usability of a pipe is useful to you in your particular project. Will you often need to sort objects by the "name" key on other arrays or other components in the future? Will this data be changing often enough and in ways that make it hard to simply sort in the component? Will you need the array sorted on any change to the view or inputs?
I created an edited plunker in which the array is sorted in the component's constructor, but there's no reason this functionality couldn't be moved out into its own method (sortValuesArray for instance) for re-use if necessary.
constructor() {
this.values.sort((a, b) => {
if (a.name < b.name) return -1;
else if (a.name > b.name) return 1;
else return 0;
});
}
Edited Plunker
回答2:
Try this
Sort from A to end of alpahbet:
this.suppliers.sort((a,b)=>a.SupplierName.localeCompare(b.SupplierName));
Z=>A (reverse order)
this.suppliers.sort((a,b)=>b.SupplierName.localeCompare(a.SupplierName));
回答3:
Your pipe expects strings but it gets objects, you should adapt it:
export class ArraySortPipe implements PipeTransform {
transform(array: Array<any>): Array<string> {
array.sort((a: any, b: any) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
return array;
}
}
回答4:
Angular still advice not to use pipes for sorting and filtering, like in angularJs.
It will slow down your application, have some performance issues. It is a lot better to provide your sorting in your component before passing it to the template.
The reason is explained on https://angular.io/guide/pipes#no-filter-pipe
If you work with a nice structured component layout you can do it even on te setter:
@Input()
set users(users: Array<User>) {
this.usersResult = (users || []).sort((a: User, b: User) => a.name < b.name ? -1 : 1)
}
回答5:
This is adaptable to any such usecase.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'sortBy'
})
export class SortByPipe implements PipeTransform {
transform(arr: Array<any>, prop: any, reverse: boolean = false): any {
if (arr === undefined) return
const m = reverse ? -1 : 1
return arr.sort((a: any, b: any): number => {
const x = a[prop]
const y = b[prop]
return (x === y) ? 0 : (x < y) ? -1*m : 1*m
})
}
}
Usage:-
<div *ngFor="let item of list | sortBy: 'isDir': true">
UPDATE
Refer Bo's answer as filtering and sorting in pipes is not recommended.
回答6:
its simple, for example if you have this array object:
cars = ["Dodge", "Fiat", "Audi", "Volvo", "BMW", "Ford"];
and you want to have the object sorted in the HTML front, use:
<li ng-repeat="x in cars | orderBy">{{x}}</li>
By default, strings are sorted alphabetically, and numbers are sorted numerically.
If you have this array with keys:
customers = [
{"name" : "Bottom-Dollar Marketse" ,"city" : "Tsawassen"},
{"name" : "Alfreds Futterkiste", "city" : "Berlin"},
{"name" : "Bon app", "city" : "Marseille"},
{"name" : "Cactus Comidas para llevar", "city" : "Buenos Aires"},
{"name" : "Bolido Comidas preparadas", "city" : "Madrid"},
{"name" : "Around the Horn", "city" : "London"},
{"name" : "B's Beverages", "city" : "London"}
];
Use:
Sort the array by "city" DESC order:
<li ng-repeat="x in customers | orderBy : '-city'">{{x.name + ", " + x.city}}</li>
Sort the array by "city":
<li ng-repeat="x in customers | orderBy : 'city'">{{x.name + ", " + x.city}}</li>