Skip to content

Commit e3764d4

Browse files
crisbetovictoriaaa234
authored andcommitted
feat(slider): support two-way binding for value (#12003)
Currently we support having a two-way binding via `ngModel`, but not through the `value` binding. These changes add support for a two-way binding on the `value`.
1 parent 0606913 commit e3764d4

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

src/lib/slider/slider.spec.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,38 @@ describe('MatSlider', () => {
13861386
});
13871387
});
13881388

1389+
describe('slider with a two-way binding', () => {
1390+
let fixture: ComponentFixture<SliderWithTwoWayBinding>;
1391+
let testComponent: SliderWithTwoWayBinding;
1392+
let sliderNativeElement: HTMLElement;
1393+
1394+
beforeEach(() => {
1395+
fixture = createComponent(SliderWithTwoWayBinding);
1396+
fixture.detectChanges();
1397+
1398+
testComponent = fixture.componentInstance;
1399+
let sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider));
1400+
sliderNativeElement = sliderDebugElement.nativeElement;
1401+
});
1402+
1403+
it('should sync the value binding in both directions', () => {
1404+
expect(testComponent.value).toBe(0);
1405+
expect(testComponent.slider.value).toBe(0);
1406+
1407+
dispatchClickEventSequence(sliderNativeElement, 0.1);
1408+
fixture.detectChanges();
1409+
1410+
expect(testComponent.value).toBe(10);
1411+
expect(testComponent.slider.value).toBe(10);
1412+
1413+
testComponent.value = 20;
1414+
fixture.detectChanges();
1415+
1416+
expect(testComponent.value).toBe(20);
1417+
expect(testComponent.slider.value).toBe(20);
1418+
});
1419+
});
1420+
13891421
});
13901422

13911423
// Disable animations and make the slider an even 100px (+ 8px padding on either side)
@@ -1552,6 +1584,15 @@ class SliderWithNativeTabindexAttr {
15521584
tabIndex: number;
15531585
}
15541586

1587+
@Component({
1588+
template: '<mat-slider [(value)]="value"></mat-slider>',
1589+
styles: [styles],
1590+
})
1591+
class SliderWithTwoWayBinding {
1592+
@ViewChild(MatSlider) slider: MatSlider;
1593+
value = 0;
1594+
}
1595+
15551596
/**
15561597
* Dispatches a click event sequence (consisting of moueseenter, click) from an element.
15571598
* Note: The mouse event truncates the position for the click.

src/lib/slider/slider.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,13 @@ export class MatSlider extends _MatSliderMixinBase
262262
/** Event emitted when the slider thumb moves. */
263263
@Output() readonly input: EventEmitter<MatSliderChange> = new EventEmitter<MatSliderChange>();
264264

265+
/**
266+
* Emits when the raw value of the slider changes. This is here primarily
267+
* to facilitate the two-way binding for the `value` input.
268+
* @docs-private
269+
*/
270+
@Output() readonly valueChange: EventEmitter<number | null> = new EventEmitter<number | null>();
271+
265272
/** The value to be used for display purposes. */
266273
get displayValue(): string | number {
267274
if (this.displayWith) {
@@ -666,6 +673,7 @@ export class MatSlider extends _MatSliderMixinBase
666673
/** Emits a change event if the current value is different from the last emitted value. */
667674
private _emitChangeEvent() {
668675
this._controlValueAccessorChangeFn(this.value);
676+
this.valueChange.emit(this.value);
669677
this.change.emit(this._createChangeEvent());
670678
}
671679

0 commit comments

Comments
 (0)