Skip to content

Commit 0d552f5

Browse files
tinayuangaojelbourn
authored andcommitted
fix(radio): only emit change event on user interaction (#1680)
1 parent 7336b90 commit 0d552f5

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

src/lib/radio/radio.spec.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,22 @@ describe('MdRadio', () => {
152152
expect(spies[1]).toHaveBeenCalledTimes(1);
153153
});
154154

155-
it('should emit a change event from the radio group', () => {
155+
it(`should not emit a change event from the radio group when change group value
156+
programmatically`, () => {
156157
expect(groupInstance.value).toBeFalsy();
157158

158159
let changeSpy = jasmine.createSpy('radio-group change listener');
159160
groupInstance.change.subscribe(changeSpy);
160161

161-
groupInstance.value = 'fire';
162+
radioLabelElements[0].click();
162163
fixture.detectChanges();
163164

164-
expect(changeSpy).toHaveBeenCalled();
165+
expect(changeSpy).toHaveBeenCalledTimes(1);
165166

166167
groupInstance.value = 'water';
167168
fixture.detectChanges();
168169

169-
expect(changeSpy).toHaveBeenCalledTimes(2);
170+
expect(changeSpy).toHaveBeenCalledTimes(1);
170171
});
171172

172173
// TODO(jelbourn): test this in an e2e test with *real* focus, rather than faking
@@ -234,42 +235,44 @@ describe('MdRadio', () => {
234235
}
235236
}));
236237

237-
it('should update the group\'s selected radio to null when unchecking that radio '
238-
+ 'programmatically', () => {
238+
it(`should update the group's selected radio to null when unchecking that radio
239+
programmatically`, () => {
239240
let changeSpy = jasmine.createSpy('radio-group change listener');
240241
groupInstance.change.subscribe(changeSpy);
241242
radioInstances[0].checked = true;
242243

243244
fixture.detectChanges();
244245

245-
expect(changeSpy).toHaveBeenCalled();
246+
expect(changeSpy).not.toHaveBeenCalled();
246247
expect(groupInstance.value).toBeTruthy();
247248

248249
radioInstances[0].checked = false;
249250

250251
fixture.detectChanges();
251252

252-
expect(changeSpy).toHaveBeenCalledTimes(2);
253+
expect(changeSpy).not.toHaveBeenCalled();
253254
expect(groupInstance.value).toBeFalsy();
254255
expect(radioInstances.every(radio => !radio.checked)).toBe(true);
255256
expect(groupInstance.selected).toBeNull();
256257
});
257258

258-
it('should fire a change event from the group whenever a radio checked state changes', () => {
259+
it('should not fire a change event from the group when a radio checked state changes', () => {
259260
let changeSpy = jasmine.createSpy('radio-group change listener');
260261
groupInstance.change.subscribe(changeSpy);
261262
radioInstances[0].checked = true;
262263

263264
fixture.detectChanges();
264265

265-
expect(changeSpy).toHaveBeenCalled();
266+
expect(changeSpy).not.toHaveBeenCalled();
266267
expect(groupInstance.value).toBeTruthy();
268+
expect(groupInstance.value).toBe('fire');
267269

268270
radioInstances[1].checked = true;
269271

270272
fixture.detectChanges();
271273

272-
expect(changeSpy).toHaveBeenCalledTimes(2);
274+
expect(groupInstance.value).toBe('water');
275+
expect(changeSpy).not.toHaveBeenCalled();
273276
});
274277
});
275278

src/lib/radio/radio.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,6 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
127127
this._value = newValue;
128128

129129
this._updateSelectedRadioFromValue();
130-
131-
// Only fire a change event if this isn't the first time the value is ever set.
132-
if (this._isInitialized) {
133-
this._emitChangeEvent();
134-
}
135130
}
136131
}
137132

@@ -197,11 +192,13 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
197192
}
198193

199194
/** Dispatch change event with current selection and group value. */
200-
private _emitChangeEvent(): void {
201-
let event = new MdRadioChange();
202-
event.source = this._selected;
203-
event.value = this._value;
204-
this.change.emit(event);
195+
_emitChangeEvent(): void {
196+
if (this._isInitialized) {
197+
let event = new MdRadioChange();
198+
event.source = this._selected;
199+
event.value = this._value;
200+
this.change.emit(event);
201+
}
205202
}
206203

207204
/**
@@ -418,12 +415,16 @@ export class MdRadioButton implements OnInit {
418415
// emit its event object to the `change` output.
419416
event.stopPropagation();
420417

418+
let groupValueChanged = this.radioGroup && this.value != this.radioGroup.value;
421419
this.checked = true;
422420
this._emitChangeEvent();
423421

424422
if (this.radioGroup) {
425423
this.radioGroup._controlValueAccessorChangeFn(this.value);
426424
this.radioGroup._touch();
425+
if (groupValueChanged) {
426+
this.radioGroup._emitChangeEvent();
427+
}
427428
}
428429
}
429430

0 commit comments

Comments
 (0)