Skip to content

fix(slider): support two-way binding for value #12003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/lib/slider/slider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,38 @@ describe('MatSlider', () => {
});
});

describe('slider with a two-way binding', () => {
let fixture: ComponentFixture<SliderWithTwoWayBinding>;
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)
Expand Down Expand Up @@ -1552,6 +1584,15 @@ class SliderWithNativeTabindexAttr {
tabIndex: number;
}

@Component({
template: '<mat-slider [(value)]="value"></mat-slider>',
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.
Expand Down
8 changes: 8 additions & 0 deletions src/lib/slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,13 @@ export class MatSlider extends _MatSliderMixinBase
/** Event emitted when the slider thumb moves. */
@Output() readonly input: EventEmitter<MatSliderChange> = new EventEmitter<MatSliderChange>();

/**
* 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<number | null> = new EventEmitter<number | null>();

/** The value to be used for display purposes. */
get displayValue(): string | number {
if (this.displayWith) {
Expand Down Expand Up @@ -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());
}

Expand Down