问题
There are similar questions but none of the answers have done the trick for me, so I would appreciate if you don't mark this as duplicate (unless you refer me to answer question that does solve the issue)
I have a Array of Objects result:Array<Object>=[];
which is returned with these values:
On my template, I would like to sort the response based on count of 'likes'
<tr class *ngFor="let media of (result) | orderBy: 'data.likes.count'">
<td>
<img src={{media.data.images.standard_resolution.url}} height="100" width="100">
<p> {{media.data.likes.count}} </p>
</td>
</tr>
The sort pipe looks like this:
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'orderBy', pure: false})
export class SortPipe {
transform(array: Array<Object>, args: string): Array<Object> {
console.log("calling pipe");
if (array == null) {
return null;
}
array.sort((a: any, b: any) => {
if (a[args] < b[args] ){
//a is the Object and args is the orderBy condition (data.likes.count in this case)
return -1;
}else if( a[args] > b[args] ){
return 1;
}else{
return 0;
}
});
return array;
}
}
When I run this code, it shows me an unordered response, rather then sorting it based on the likes. I should point that that when I do console.log(a[args])
on the pipe I get undefined so I am probably not reading the value in the object field correctly.
回答1:
You can't pass args like that
Should be :
array.sort((a: any, b: any) => {
if (a.data.likes[args] < b.data.likes[args] ){
//a is the Object and args is the orderBy condition (data.likes.count in this case)
return -1;
}else if( a.data.likes[args] > b.data.likes[args] ){
return 1;
}else{
return 0;
}
});
And then in your template :
<tr class *ngFor="let media of (result) | orderBy: 'count'">
And if you really want to do what you're doing ( I really discourage ) , you need to use a helper to parse your data.likes.count
and return the deeper object.
function goDeep(obj, desc) {
var arr = desc.split(".");
while(arr.length && (obj = obj[arr.shift()]));
return obj;
}
Then you can use it like
array.sort((a: any, b: any) => {
let aDeep = goDeep(a,args);
let bDeep = goDeep(b,args);
if (aDeep < bDeep ){
//a is the Object and args is the orderBy condition (data.likes.count in this case)
return -1;
}else if( aDeep > bDeep ){
return 1;
}else{
return 0;
}
});
And then you can use it like you wanted ;
<tr class *ngFor="let media of (result) | orderBy: 'data.likes.count'">
来源:https://stackoverflow.com/questions/41381505/pipes-angular-2-sort-array-of-objects