From c82fca8626b8400861a0e79a57677d71e3ef5b4b Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 29 Sep 2017 22:13:35 +0200 Subject: [PATCH] fix(slide-toggle): report change to model before firing a change event (#7076) 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 bf50e88ec22..c4234540c72 100644 --- a/src/lib/slide-toggle/slide-toggle.spec.ts +++ b/src/lib/slide-toggle/slide-toggle.spec.ts @@ -563,7 +563,8 @@ describe('MatSlideToggle with forms', () => { declarations: [ SlideToggleWithForm, SlideToggleWithModel, - SlideToggleWithFormControl + SlideToggleWithFormControl, + SlideToggleWithModelAndChangeEvent, ] }); @@ -795,6 +796,24 @@ describe('MatSlideToggle 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 1bd02ed5ed4..240052f138e 100644 --- a/src/lib/slide-toggle/slide-toggle.ts +++ b/src/lib/slide-toggle/slide-toggle.ts @@ -251,8 +251,8 @@ export class MatSlideToggle extends _MatSlideToggleMixinBase implements OnDestro let event = new MatSlideToggleChange(); event.source = this; event.checked = this.checked; - this.change.emit(event); this.onChange(this.checked); + this.change.emit(event); } _onDragStart() {