fix(radio): fix radio group behavior on change (#1735)

This commit is contained in:
tinayuangao
2016-11-14 13:29:23 -08:00
committed by Kara
parent b9fe75af83
commit bbc5f6a954
2 changed files with 61 additions and 25 deletions
+23
View File
@@ -285,6 +285,29 @@ describe('MdRadio', () => {
expect(groupInstance.value).toBe('water');
expect(changeSpy).not.toHaveBeenCalled();
});
it(`should update checked status if changed value to radio group's value`, () => {
let changeSpy = jasmine.createSpy('radio-group change listener');
groupInstance.change.subscribe(changeSpy);
groupInstance.value = 'apple';
expect(changeSpy).not.toHaveBeenCalled();
expect(groupInstance.value).toBe('apple');
expect(groupInstance.selected).toBeFalsy('expect group selected to be null');
expect(radioInstances[0].checked).toBeFalsy('should not select the first button');
expect(radioInstances[1].checked).toBeFalsy('should not select the second button');
expect(radioInstances[2].checked).toBeFalsy('should not select the third button');
radioInstances[0].value = 'apple';
fixture.detectChanges();
expect(groupInstance.selected).toBe(
radioInstances[0], 'expect group selected to be first button');
expect(radioInstances[0].checked).toBeTruthy('expect group select the first button');
expect(radioInstances[1].checked).toBeFalsy('should not select the second button');
expect(radioInstances[2].checked).toBeFalsy('should not select the third button');
});
});
describe('group with ngModel', () => {
+38 -25
View File
@@ -127,6 +127,13 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
this._value = newValue;
this._updateSelectedRadioFromValue();
this._checkSelectedRadioButton();
}
}
_checkSelectedRadioButton() {
if (this.selected && !this._selected.checked) {
this._selected.checked = true;
}
}
@@ -139,9 +146,7 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
this._selected = selected;
this.value = selected ? selected.value : null;
if (selected && !selected.checked) {
selected.checked = true;
}
this._checkSelectedRadioButton();
}
/**
@@ -180,14 +185,13 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
let isAlreadySelected = this._selected != null && this._selected.value == this._value;
if (this._radios != null && !isAlreadySelected) {
let matchingRadio = this._radios.filter(radio => radio.value == this._value)[0];
if (matchingRadio) {
this.selected = matchingRadio;
} else if (this.value == null) {
this.selected = null;
this._radios.forEach(radio => { radio.checked = false; });
}
this._selected = null;
this._radios.forEach(radio => {
radio.checked = this.value == radio.value;
if (radio.checked) {
this._selected = radio;
}
});
}
}
@@ -303,19 +307,21 @@ export class MdRadioButton implements OnInit {
}
set checked(newCheckedState: boolean) {
this._checked = newCheckedState;
if (this._checked != newCheckedState) {
this._checked = newCheckedState;
if (newCheckedState && this.radioGroup && this.radioGroup.value != this.value) {
this.radioGroup.selected = this;
} else if (!newCheckedState && this.radioGroup && this.radioGroup.value == this.value) {
// When unchecking the selected radio button, update the selected radio
// property on the group.
this.radioGroup.selected = null;
}
if (newCheckedState && this.radioGroup && this.radioGroup.value != this.value) {
this.radioGroup.selected = this;
} else if (!newCheckedState && this.radioGroup && this.radioGroup.value == this.value) {
// When unchecking the selected radio button, update the selected radio
// property on the group.
this.radioGroup.selected = null;
}
if (newCheckedState) {
// Notify all radio buttons with the same name to un-check.
this.radioDispatcher.notify(this.id, this.name);
if (newCheckedState) {
// Notify all radio buttons with the same name to un-check.
this.radioDispatcher.notify(this.id, this.name);
}
}
}
@@ -327,10 +333,17 @@ export class MdRadioButton implements OnInit {
set value(value: any) {
if (this._value != value) {
if (this.radioGroup != null && this.checked) {
this.radioGroup.value = value;
}
this._value = value;
if (this.radioGroup != null) {
if (!this.checked) {
// Update checked when the value changed to match the radio group's value
this.checked = this.radioGroup.value == value;
}
if (this.checked) {
this.radioGroup.selected = this;
}
}
}
}