Angular4 - 使用管道排序数据

时间:2018-04-04 21:43:49

标签: angular pipe angular-pipe

我必须使用Angular4x订购一个列表,我找不到一个简单的例子来了解它是如何工作的。似乎使用AngularJs它更容易,我想做那样的事情。

ng-repeat="x in customers | orderBy : 'city'"
顺便说一句,如果你能帮助我,我真的很感激。

由于 安德莉亚

1 个答案:

答案 0 :(得分:1)

我碰巧有一个躺着。但请小心,正如Ali Sajid所指出的那样,这些管道are not part of the default Angular implementation for good reasons。因此,要知道您不应该将此管道用于大型列表/表格,或者如果您想积极缩小代码。

有人说,这是我使用的管道:

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']">

属性名称前面的+-表示升序/降序。