diff --git a/src/cdk/collections/selection.spec.ts b/src/cdk/collections/selection.spec.ts index 146758053499..024192f97713 100644 --- a/src/cdk/collections/selection.spec.ts +++ b/src/cdk/collections/selection.spec.ts @@ -1,4 +1,4 @@ -import {SelectionModel} from './selection'; +import {getMultipleValuesInSingleSelectionError, SelectionModel} from './selection'; describe('SelectionModel', () => { @@ -22,6 +22,10 @@ describe('SelectionModel', () => { expect(model.isSelected(2)).toBe(true); }); + it('should throw an error if multiple values are passed to model', () => { + expect(() => model.select(1, 2)).toThrow(getMultipleValuesInSingleSelectionError()); + }); + it('should only preselect one value', () => { model = new SelectionModel(false, [1, 2]); @@ -36,13 +40,29 @@ describe('SelectionModel', () => { beforeEach(() => model = new SelectionModel(true)); - it('should be able to select multiple options at the same time', () => { + it('should be able to select multiple options', () => { + const onChangeSpy = jasmine.createSpy('onChange spy'); + + model.onChange!.subscribe(onChangeSpy); model.select(1); model.select(2); expect(model.selected.length).toBe(2); expect(model.isSelected(1)).toBe(true); expect(model.isSelected(2)).toBe(true); + expect(onChangeSpy).toHaveBeenCalledTimes(2); + }); + + it('should be able to select multiple options at the same time', () => { + const onChangeSpy = jasmine.createSpy('onChange spy'); + + model.onChange!.subscribe(onChangeSpy); + model.select(1, 2); + + expect(model.selected.length).toBe(2); + expect(model.isSelected(1)).toBe(true); + expect(model.isSelected(2)).toBe(true); + expect(onChangeSpy).toHaveBeenCalledTimes(1); }); it('should be able to preselect multiple options', () => { diff --git a/src/cdk/collections/selection.ts b/src/cdk/collections/selection.ts index b2c199cfc9ef..722cc16c1717 100644 --- a/src/cdk/collections/selection.ts +++ b/src/cdk/collections/selection.ts @@ -56,16 +56,18 @@ export class SelectionModel { /** * Selects a value or an array of values. */ - select(value: T): void { - this._markSelected(value); + select(...values: T[]): void { + this._verifyValueAssignment(values); + values.forEach(value => this._markSelected(value)); this._emitChangeEvent(); } /** * Deselects a value or an array of values. */ - deselect(value: T): void { - this._unmarkSelected(value); + deselect(...values: T[]): void { + this._verifyValueAssignment(values); + values.forEach(value => this._unmarkSelected(value)); this._emitChangeEvent(); } @@ -162,6 +164,16 @@ export class SelectionModel { this._selection.forEach(value => this._unmarkSelected(value)); } } + + /** + * Verifies the value assignment and throws an error if the specified value array is + * including multiple values while the selection model is not supporting multiple values. + */ + private _verifyValueAssignment(values: T[]) { + if (values.length > 1 && !this._isMulti) { + throw getMultipleValuesInSingleSelectionError(); + } + } } /** @@ -171,3 +183,11 @@ export class SelectionModel { export class SelectionChange { constructor(public added?: T[], public removed?: T[]) { } } + +/** + * Returns an error that reports that multiple values are passed into a selection model + * with a single value. + */ +export function getMultipleValuesInSingleSelectionError() { + return Error('Cannot pass multiple values into SelectionModel with single-value mode.'); +}