Angular4 - 使用管道对数据进行排序

Angular4 - sorting data with pipe

我必须用 Angular4x 订购一个列表,但我找不到一个简单的例子来理解它是如何工作的。好像有了 AngularJs 就更容易了,我想做这样的事情。

ng-repeat="x in customers | orderBy : 'city'"

顺便说一下,如果你能帮助我,我将不胜感激。

谢谢 安德里亚

我身边正好有一个。但请注意这一点,正如 Ali Sajid 也指出的那样,这些管道 are not part of the default Angular implementation for good reasons。所以要知道你不应该将这个管道用于巨大的 lists/tables 或者如果你想积极地缩小你的代码。

话虽如此,这是我使用的管道:

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

@Pipe({ name: 'orderBy' })
export class OrderByPipe implements PipeTransform {
    static compare(reverse: boolean, a: any, b: any): number {
        if (a < b && reverse === false) {
            return -1;
        }
        if (a > b && reverse === false) {
            return 1;
        }
        if (a < b && reverse === true) {
            return 1;
        }
        if (a > b && reverse === true) {
            return -1;
        }
        return 0;
    }

    transform(input: any[], config?: string | string[]): any {
        if(!input) {
            return input;
        }

        if (config === '+' || config === '-') {
            return config === '+' ? input.sort() : input.sort().reverse();
        }

        if (Array.isArray(config) === false) {
            config = <string[]>[config];
        }

        // As soon as a or b is smaller/greater than the other, we can immediately return
        return input.sort((a: any, b: any): number => {
            for (let fullProp of config) {
                let reverse = fullProp[0] === '-';
                let prop = fullProp.substr(1);

                // Is it a subobject?
                if (prop.indexOf('.') > 0) {
                    let first = prop.split('.')[0];
                    let last = prop.split('.')[1];

                    let result = OrderByPipe.compare(reverse, a[first][last], b[first][last]);
                    if (result !== 0) {
                        return result;
                    }

                    continue;
                }

                let result = OrderByPipe.compare(reverse, a[prop], b[prop]);
                if (result !== 0) {
                    return result;
                }
            };

            return 0;
        });
    }
}

此管道的测试:

import { OrderByPipe } from './order-by.pipe';

describe('Pipe: OrderBy', () => {
    let orderBy: OrderByPipe;

    beforeEach(() => {
        orderBy = new OrderByPipe();
    });

    it('should sort an array in ascending order', () => {
        let data = [5, 3, 1, 2, 4];
        let result = [1, 2, 3, 4, 5];
        expect(orderBy.transform(data, '+')).toEqual(result);
    });

    it('should sort an array in descending order', () => {
        let data = [5, 3, 1, 2, 4];
        let result = [5, 4, 3, 2, 1];
        expect(orderBy.transform(data, '-')).toEqual(result);
    });

    it('should sort an array in ascending order based on a property', () => {
        let data = [{ q: 1 }, { q: 8 }, { q: 5 }];
        let result = [{ q: 1 }, { q: 5 }, { q: 8 }];
        expect(orderBy.transform(data, '+q')).toEqual(result);
    });

    it('should sort an array in descending order based on a property', () => {
        let data = [{ q: 1 }, { q: 8 }, { q: 5 }];
        let result = [{ q: 8 }, { q: 5 }, { q: 1 }];
        expect(orderBy.transform(data, '-q')).toEqual(result);
    });

    it('should sort an array based on multiple properties', () => {
        let data = [{ d: 'yada' }, { d: 'something', n: 8 }, { d: 'something', n: 4 }];
        let result = [{ d: 'something', n: 4 }, { d: 'something', n: 8 }, { d: 'yada' }];
        expect(orderBy.transform(data, ['+d', '+n'])).toEqual(result);
    });

    it('should sort an array based on a nested object', () => {
        let data = [
            { d: 'something', q: { n: 8 } },
            { d: 'yada', q: { n: 3 } },
            { d: 'something', q: { n: 4 } }
        ];
        let result = [
            { d: 'yada', q: { n: 3 } },
            { d: 'something', q: { n: 4 } },
            { d: 'something', q: { n: 8 } }
        ];
        expect(orderBy.transform(data, '+q.n')).toEqual(result);
    });

    it('should handle empty values gracefully', () => {
        expect(orderBy.transform(undefined)).toBe(undefined);
    });
});

以及用法:

<li *ngFor="let item of data | orderBy: ['-date']">

属性名字前面的+-表示ascending/descending.