Skip to content

Commit c82fca8

Browse files
devversionandrewseguin
authored andcommitted
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
1 parent 504ba70 commit c82fca8

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/lib/slide-toggle/slide-toggle.spec.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,8 @@ describe('MatSlideToggle with forms', () => {
563563
declarations: [
564564
SlideToggleWithForm,
565565
SlideToggleWithModel,
566-
SlideToggleWithFormControl
566+
SlideToggleWithFormControl,
567+
SlideToggleWithModelAndChangeEvent,
567568
]
568569
});
569570

@@ -795,6 +796,24 @@ describe('MatSlideToggle with forms', () => {
795796
expect(testComponent.isSubmitted).toBe(true);
796797
});
797798
});
799+
800+
describe('with model and change event', () => {
801+
it('should report changes to NgModel before emitting change event', () => {
802+
const fixture = TestBed.createComponent(SlideToggleWithModelAndChangeEvent);
803+
fixture.detectChanges();
804+
805+
const labelEl = fixture.debugElement.query(By.css('label')).nativeElement;
806+
807+
spyOn(fixture.componentInstance, 'onChange').and.callFake(() => {
808+
expect(fixture.componentInstance.checked)
809+
.toBe(true, 'Expected the model value to have changed before the change event fired.');
810+
});
811+
812+
labelEl.click();
813+
814+
expect(fixture.componentInstance.onChange).toHaveBeenCalledTimes(1);
815+
});
816+
});
798817
});
799818

800819
@Component({
@@ -873,3 +892,11 @@ class SlideToggleWithTabindexAttr {}
873892
class SlideToggleWithoutLabel {
874893
label: string;
875894
}
895+
896+
@Component({
897+
template: `<md-slide-toggle [(ngModel)]="checked" (change)="onChange()"></md-slide-toggle>`
898+
})
899+
class SlideToggleWithModelAndChangeEvent {
900+
checked: boolean;
901+
onChange: () => void = () => {};
902+
}

src/lib/slide-toggle/slide-toggle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,8 @@ export class MatSlideToggle extends _MatSlideToggleMixinBase implements OnDestro
251251
let event = new MatSlideToggleChange();
252252
event.source = this;
253253
event.checked = this.checked;
254-
this.change.emit(event);
255254
this.onChange(this.checked);
255+
this.change.emit(event);
256256
}
257257

258258
_onDragStart() {

0 commit comments

Comments
 (0)