diff --git a/packages/common/src/pipes/keyvalue_pipe.ts b/packages/common/src/pipes/keyvalue_pipe.ts index 163b83f3e6..a287bb6e5a 100644 --- a/packages/common/src/pipes/keyvalue_pipe.ts +++ b/packages/common/src/pipes/keyvalue_pipe.ts @@ -49,6 +49,7 @@ export class KeyValuePipe implements PipeTransform { private differ!: KeyValueDiffer; private keyValues: Array> = []; + private compareFn: (a: KeyValue, b: KeyValue) => number = defaultComparator; /* * NOTE: when the `input` value is a simple Record object, the keys are extracted with @@ -91,13 +92,17 @@ export class KeyValuePipe implements PipeTransform { } const differChanges: KeyValueChanges|null = this.differ.diff(input as any); + const compareFnChanged = compareFn !== this.compareFn; if (differChanges) { this.keyValues = []; differChanges.forEachItem((r: KeyValueChangeRecord) => { this.keyValues.push(makeKeyValuePair(r.key, r.currentValue!)); }); + } + if (differChanges || compareFnChanged) { this.keyValues.sort(compareFn); + this.compareFn = compareFn; } return this.keyValues; } diff --git a/packages/common/test/pipes/keyvalue_pipe_spec.ts b/packages/common/test/pipes/keyvalue_pipe_spec.ts index 2b9fb49533..cbbfeea895 100644 --- a/packages/common/test/pipes/keyvalue_pipe_spec.ts +++ b/packages/common/test/pipes/keyvalue_pipe_spec.ts @@ -51,6 +51,15 @@ describe('KeyValuePipe', () => { {key: 'a', value: 1}, {key: 'b', value: 1} ]); }); + it('should reorder when compareFn changes', () => { + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + const input = {'b': 1, 'a': 2}; + pipe.transform(input); + expect(pipe.transform(input, (a, b) => a.value - b.value)).toEqual([ + {key: 'b', value: 1}, + {key: 'a', value: 2}, + ]); + }); it('should return the same ref if nothing changes', () => { const pipe = new KeyValuePipe(defaultKeyValueDiffers); const transform1 = pipe.transform({1: 2}); @@ -114,6 +123,15 @@ describe('KeyValuePipe', () => { {key: {id: 1}, value: 1}, ]); }); + it('should reorder when compareFn changes', () => { + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + const input = new Map([['b', 1], ['a', 2]]); + pipe.transform(input); + expect(pipe.transform(input, (a, b) => a.value - b.value)).toEqual([ + {key: 'b', value: 1}, + {key: 'a', value: 2}, + ]); + }); it('should return the same ref if nothing changes', () => { const pipe = new KeyValuePipe(defaultKeyValueDiffers); const transform1 = pipe.transform(new Map([[1, 2]]));