From 41be0d4282b04a2740a0c12b689d3b6cbe53a060 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 14 Sep 2017 18:03:10 +0200 Subject: [PATCH] fix(slide-toggle): report change to model before firing a change event Whenever the value of the slide-toggle changes through interaction, a `change` event will be emitted. The value change then will be reported to the `ControlValueAccessor` which fires the `ngModelChange` output. Right now the `ngModelChange` output fires after the normal `change` output. This should be the other way around because developers expect the two-way data binding to already reflect the change. Fixes #7074 --- src/lib/slide-toggle/slide-toggle.spec.ts | 29 ++++++++++++++++++++++- src/lib/slide-toggle/slide-toggle.ts | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/lib/slide-toggle/slide-toggle.spec.ts b/src/lib/slide-toggle/slide-toggle.spec.ts index 345dcb5e418c..57b5a8555674 100644 --- a/src/lib/slide-toggle/slide-toggle.spec.ts +++ b/src/lib/slide-toggle/slide-toggle.spec.ts @@ -563,7 +563,8 @@ describe('MdSlideToggle with forms', () => { declarations: [ SlideToggleWithForm, SlideToggleWithModel, - SlideToggleWithFormControl + SlideToggleWithFormControl, + SlideToggleWithModelAndChangeEvent, ] }); @@ -795,6 +796,24 @@ describe('MdSlideToggle with forms', () => { expect(testComponent.isSubmitted).toBe(true); }); }); + + describe('with model and change event', () => { + it('should report changes to NgModel before emitting change event', () => { + const fixture = TestBed.createComponent(SlideToggleWithModelAndChangeEvent); + fixture.detectChanges(); + + const labelEl = fixture.debugElement.query(By.css('label')).nativeElement; + + spyOn(fixture.componentInstance, 'onChange').and.callFake(() => { + expect(fixture.componentInstance.checked) + .toBe(true, 'Expected the model value to have changed before the change event fired.'); + }); + + labelEl.click(); + + expect(fixture.componentInstance.onChange).toHaveBeenCalledTimes(1); + }); + }); }); @Component({ @@ -873,3 +892,11 @@ class SlideToggleWithTabindexAttr {} class SlideToggleWithoutLabel { label: string; } + +@Component({ + template: `` +}) +class SlideToggleWithModelAndChangeEvent { + checked: boolean; + onChange: () => void = () => {}; +} diff --git a/src/lib/slide-toggle/slide-toggle.ts b/src/lib/slide-toggle/slide-toggle.ts index 8b5d13de0d04..0c4eec296d10 100644 --- a/src/lib/slide-toggle/slide-toggle.ts +++ b/src/lib/slide-toggle/slide-toggle.ts @@ -247,8 +247,8 @@ export class MdSlideToggle extends _MdSlideToggleMixinBase implements OnDestroy, let event = new MdSlideToggleChange(); event.source = this; event.checked = this.checked; - this.change.emit(event); this.onChange(this.checked); + this.change.emit(event); } _onDragStart() {