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.
我必须用 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.