fix(common): re-sort output of `KeyValuePipe` when `compareFn` changes (#42821)
Previously, if only the `compareFn` changed but the data itself did not, then the `KeyValuePipe` did not re-sort the output. Fixes #42819 PR Close #42821
This commit is contained in:
parent
81dce5c664
commit
e42aa6c13b
|
@ -49,6 +49,7 @@ export class KeyValuePipe implements PipeTransform {
|
||||||
|
|
||||||
private differ!: KeyValueDiffer<any, any>;
|
private differ!: KeyValueDiffer<any, any>;
|
||||||
private keyValues: Array<KeyValue<any, any>> = [];
|
private keyValues: Array<KeyValue<any, any>> = [];
|
||||||
|
private compareFn: (a: KeyValue<any, any>, b: KeyValue<any, any>) => number = defaultComparator;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: when the `input` value is a simple Record<K, V> object, the keys are extracted with
|
* NOTE: when the `input` value is a simple Record<K, V> object, the keys are extracted with
|
||||||
|
@ -91,13 +92,17 @@ export class KeyValuePipe implements PipeTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
const differChanges: KeyValueChanges<K, V>|null = this.differ.diff(input as any);
|
const differChanges: KeyValueChanges<K, V>|null = this.differ.diff(input as any);
|
||||||
|
const compareFnChanged = compareFn !== this.compareFn;
|
||||||
|
|
||||||
if (differChanges) {
|
if (differChanges) {
|
||||||
this.keyValues = [];
|
this.keyValues = [];
|
||||||
differChanges.forEachItem((r: KeyValueChangeRecord<K, V>) => {
|
differChanges.forEachItem((r: KeyValueChangeRecord<K, V>) => {
|
||||||
this.keyValues.push(makeKeyValuePair(r.key, r.currentValue!));
|
this.keyValues.push(makeKeyValuePair(r.key, r.currentValue!));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
if (differChanges || compareFnChanged) {
|
||||||
this.keyValues.sort(compareFn);
|
this.keyValues.sort(compareFn);
|
||||||
|
this.compareFn = compareFn;
|
||||||
}
|
}
|
||||||
return this.keyValues;
|
return this.keyValues;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,15 @@ describe('KeyValuePipe', () => {
|
||||||
{key: 'a', value: 1}, {key: 'b', value: 1}
|
{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<string, number>(input);
|
||||||
|
expect(pipe.transform<string, number>(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', () => {
|
it('should return the same ref if nothing changes', () => {
|
||||||
const pipe = new KeyValuePipe(defaultKeyValueDiffers);
|
const pipe = new KeyValuePipe(defaultKeyValueDiffers);
|
||||||
const transform1 = pipe.transform({1: 2});
|
const transform1 = pipe.transform({1: 2});
|
||||||
|
@ -114,6 +123,15 @@ describe('KeyValuePipe', () => {
|
||||||
{key: {id: 1}, value: 1},
|
{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<string, number>(input);
|
||||||
|
expect(pipe.transform<string, number>(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', () => {
|
it('should return the same ref if nothing changes', () => {
|
||||||
const pipe = new KeyValuePipe(defaultKeyValueDiffers);
|
const pipe = new KeyValuePipe(defaultKeyValueDiffers);
|
||||||
const transform1 = pipe.transform(new Map([[1, 2]]));
|
const transform1 = pipe.transform(new Map([[1, 2]]));
|
||||||
|
|
Loading…
Reference in New Issue