Pipes Angular 2:排序对象数组

时间:2016-12-29 14:19:53

标签: angular angular2-template

有类似的问题,但没有一个答案为我做了诀窍,所以如果你不把它标记为重复,我将不胜感激(除非你引用我回答确实解决问题的问题)

我有一个对象数组result:Array<Object>=[];,它返回这些值: Array Object data

在我的模板上,我想根据“赞”的数量对响应进行排序

<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>

排序管道如下所示:

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;
  }
}

当我运行此代码时,它会向我显示无序响应,而不是根据喜欢对其进行排序。我应该指出,当我在管道上console.log(a[args])时,我得到了未定义,所以我可能没有正确读取对象字段中的值。

1 个答案:

答案 0 :(得分:4)

你无法传递这样的args

应该是:

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;
        }
    });

然后在你的模板中:

<tr class *ngFor="let media of (result) | orderBy: 'count'">

如果你真的想做你正在做的事情(我真的不鼓励),你需要使用帮助器来解析你的data.likes.count并返回更深层的对象。

function goDeep(obj, desc) {
    var arr = desc.split(".");
    while(arr.length && (obj = obj[arr.shift()]));
    return obj;
}

然后你可以像

一样使用它
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;
            }
        });

然后你可以按照自己的意愿使用它;

<tr class *ngFor="let media of (result) | orderBy: 'data.likes.count'">