Skip to content

Commit 837d396

Browse files
stijnvnmmalerba
authored andcommitted
fix(cdk/collections): Do not deselect comparable already selected value with setSelection (#28267)
(cherry picked from commit 58d4958)
1 parent 69294e4 commit 837d396

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/cdk/collections/selection-model.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class SelectionModel<T> {
9494
const newSelectedSet = new Set(values);
9595
values.forEach(value => this._markSelected(value));
9696
oldValues
97-
.filter(value => !newSelectedSet.has(value))
97+
.filter(value => !newSelectedSet.has(this._getConcreteValue(value, newSelectedSet)))
9898
.forEach(value => this._unmarkSelected(value));
9999
const changed = this._hasQueuedChanges();
100100
this._emitChangeEvent();
@@ -234,11 +234,12 @@ export class SelectionModel<T> {
234234
}
235235

236236
/** Returns a value that is comparable to inputValue by applying compareWith function, returns the same inputValue otherwise. */
237-
private _getConcreteValue(inputValue: T): T {
237+
private _getConcreteValue(inputValue: T, selection?: Set<T>): T {
238238
if (!this.compareWith) {
239239
return inputValue;
240240
} else {
241-
for (let selectedValue of this._selection) {
241+
selection = selection ?? this._selection;
242+
for (let selectedValue of selection) {
242243
if (this.compareWith!(inputValue, selectedValue)) {
243244
return selectedValue;
244245
}

src/cdk/collections/selection.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,19 @@ describe('SelectionModel', () => {
299299
model.deselect(v2);
300300
expect(model.selected.length).toBe(1);
301301
});
302+
303+
describe('setSelection', () => {
304+
it('should not deselect an already selected value', () => {
305+
type Item = {key: number; value: string};
306+
const v1: Item = {key: 1, value: 'blue'};
307+
const v2: Item = {key: 1, value: 'apple'};
308+
const compareFun = (x: Item, y: Item) => x.key === y.key;
309+
const model = new SelectionModel<Item>(false, [v1], false, compareFun);
310+
311+
model.setSelection(v2);
312+
313+
expect(model.selected.length).toBe(1);
314+
expect(compareFun(model.selected[0], v2)).toBeTruthy();
315+
});
316+
});
302317
});

0 commit comments

Comments
 (0)