diff --git a/src/lib/slider/slider.spec.ts b/src/lib/slider/slider.spec.ts index b53a6be2408a..9f99457cecda 100644 --- a/src/lib/slider/slider.spec.ts +++ b/src/lib/slider/slider.spec.ts @@ -1386,6 +1386,38 @@ describe('MatSlider', () => { }); }); + describe('slider with a two-way binding', () => { + let fixture: ComponentFixture; + let testComponent: SliderWithTwoWayBinding; + let sliderNativeElement: HTMLElement; + + beforeEach(() => { + fixture = createComponent(SliderWithTwoWayBinding); + fixture.detectChanges(); + + testComponent = fixture.componentInstance; + let sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider)); + sliderNativeElement = sliderDebugElement.nativeElement; + }); + + it('should sync the value binding in both directions', () => { + expect(testComponent.value).toBe(0); + expect(testComponent.slider.value).toBe(0); + + dispatchClickEventSequence(sliderNativeElement, 0.1); + fixture.detectChanges(); + + expect(testComponent.value).toBe(10); + expect(testComponent.slider.value).toBe(10); + + testComponent.value = 20; + fixture.detectChanges(); + + expect(testComponent.value).toBe(20); + expect(testComponent.slider.value).toBe(20); + }); + }); + }); // Disable animations and make the slider an even 100px (+ 8px padding on either side) @@ -1552,6 +1584,15 @@ class SliderWithNativeTabindexAttr { tabIndex: number; } +@Component({ + template: '', + styles: [styles], +}) +class SliderWithTwoWayBinding { + @ViewChild(MatSlider) slider: MatSlider; + value = 0; +} + /** * Dispatches a click event sequence (consisting of moueseenter, click) from an element. * Note: The mouse event truncates the position for the click. diff --git a/src/lib/slider/slider.ts b/src/lib/slider/slider.ts index 49b3f001e35e..86d7b949b681 100644 --- a/src/lib/slider/slider.ts +++ b/src/lib/slider/slider.ts @@ -262,6 +262,13 @@ export class MatSlider extends _MatSliderMixinBase /** Event emitted when the slider thumb moves. */ @Output() readonly input: EventEmitter = new EventEmitter(); + /** + * Emits when the raw value of the slider changes. This is here primarily + * to facilitate the two-way binding for the `value` input. + * @docs-private + */ + @Output() readonly valueChange: EventEmitter = new EventEmitter(); + /** The value to be used for display purposes. */ get displayValue(): string | number { if (this.displayWith) { @@ -660,6 +667,7 @@ export class MatSlider extends _MatSliderMixinBase /** Emits a change event if the current value is different from the last emitted value. */ private _emitChangeEvent() { this._controlValueAccessorChangeFn(this.value); + this.valueChange.emit(this.value); this.change.emit(this._createChangeEvent()); }