Angular 2.如何申请orderBy?

时间:2016-02-17 15:39:45

标签: javascript angular

我有一段代码。

<table class="table table-bordered table-condensed" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th>#</th>
            <th>Name</th>
            <th>Score</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="#participant of participants; #i = index">
            <td>{{i+1}}</td>
            <td>{{participant.username}}</td>
            <td>{{participant.score}}</td>
        </tr>
    </tbody>
</table>

在Angular 1中,我有 orderBy 过滤器来按我的过滤器对行进行排序。但是我怎样才能以相同的方式在Angular 2中进行orderBy?谢谢。

4 个答案:

答案 0 :(得分:14)

您需要为此实现自定义管道。这对应于创建一个由@Pipe修饰的类。这是一个例子。它的转换方法实际上将处理列表,您可以根据需要对其进行排序:

import { Pipe } from "angular2/core";

@Pipe({
  name: "orderby"
})
export class OrderByPipe {
  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;
  }
}

然后,您可以在表达式中使用此管道,如下所述。例如在ngFor中。不要忘记将管道指定到您使用它的组件的pipes属性中:

@Component({
  (...)
  template: `
    <li *ngFor="list | orderby"> (...) </li>
  `,
  pipes: [ OrderByPipe ]
})
(...)

答案 1 :(得分:12)

如果您使用lodash,您的管道可能是这样的:

import { Pipe, PipeTransform } from '@angular/core';
import { orderBy } from 'lodash';

@Pipe({
  name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {
  transform = orderBy;
}

然后你可以使用该方法的所有功能:

<li *ngFor="let product of products | orderBy: 'price': 'desc'">
  {{product.name}}
</li>

答案 2 :(得分:4)

感谢您的回答。我在下面写了可行的代码:

@Pipe({name: 'orderBy'})

export class orderBy implements PipeTransform {
    transform(obj: any, orderFields: string): any {
        orderFields.forEach(function(currentField) {
            var orderType = 'ASC';

            if (currentField[0] === '-') {
                currentField = currentField.substring(1);
                orderType = 'DESC';
            }

            obj.sort(function(a, b) {
                if (orderType === 'ASC') {
                    if (a[currentField] < b[currentField]) return -1;
                    if (a[currentField] > b[currentField]) return 1;
                    return 0;
                } else {
                    if (a[currentField] < b[currentField]) return 1;
                    if (a[currentField] > b[currentField]) return -1;
                    return 0;
                }
            });

        });
        return obj;
    }
}

此代码考虑订单方向DESC或ASC。用法:

<tr *ngFor="#participant of participants | orderBy: '-score'; #i = index">

答案 3 :(得分:0)

我知道的最新lib

https://www.npmjs.com/package/ngx-pipes

const numbers = [2, 1, 3];
 
const obj = [
  {id: 4, name: 'Dave', amount: 2},
  {id: 2, name: 'Michael', amount: 2},
  {id: 3, name: 'Dan', amount: 1},
  {id: 1, name: 'John', amount: 1}
];
 
const deepObj = [
  {id: 1, name: 'John', amount: 1337, deep: {prop: 4}},
  {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}},
  {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}},
  {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}}
];

<!-- Returns array ordered by value -->
<p>{{ numbers | orderBy }}</p>  <!-- Output: [1, 2, 3] -->
<p>{{ numbers | orderBy: '-' }}</p>  <!-- Output: [3, 2, 1] -->
 
<!-- Returns array ordered by value of property -->
<p>{{ deepObj | orderBy: 'amount' }}</p>  
<!-- Output: [{id: 3, ...}, {id: 4, ...}, {id: 2, ...}, {id: 1, ...}] -->
<p>{{ deepObj | orderBy: '-amount' }}</p>  
<!-- Output: [{id: 1, ...}, {id: 2, ...}, {id: 4, ...}, {id: 3, ...}] -->
 
<!-- Returns array ordered by value of deep property -->
<p>{{ deepObj | orderBy: 'deep.prop' }}</p>  
<!-- Output: [{id: 3, ...}, {id: 2, ...}, {id: 4, ...}, {id: 1, ...}] -->
<p>{{ deepObj | orderBy: '-deep.prop' }}</p>  
<!-- Output: [{id: 1, ...}, {id: 4, ...}, {id: 2, ...}, {id: 3, ...}] -->
 
<!-- Returns array ordered by mutliple properties -->
<p>{{ obj | orderBy: ['amount', 'id'] }}</p>  
<!-- Output: [{id: 1, ...}, {id: 3, ...}, {id: 2, ...}, {id: 4, ...}] -->