fix(button-toggle): selected value not being maintained when changing value while toggles are being swapped out (#10707)

Fixes a regression that caused the button toggle group not maintaining the selected state if the selected value and the set of button toggles are swapped out at the same time.

Fixes #10690.
This commit is contained in:
Kristiyan Kostadinov
2018-04-12 22:03:20 +02:00
committed by tinayuangao
parent 023e8f4770
commit dec91ce08f
2 changed files with 27 additions and 10 deletions
@@ -677,6 +677,22 @@ describe('MatButtonToggle without forms', () => {
expect(fixture.componentInstance.toggleGroup.value).toBe('Two');
expect(fixture.componentInstance.toggles.toArray()[1].checked).toBe(true);
});
it('should maintain the selected state when the value and toggles are swapped out at ' +
'the same time', () => {
const fixture = TestBed.createComponent(RepeatedButtonTogglesWithPreselectedValue);
fixture.detectChanges();
expect(fixture.componentInstance.toggleGroup.value).toBe('Two');
expect(fixture.componentInstance.toggles.toArray()[1].checked).toBe(true);
fixture.componentInstance.possibleValues = ['Five', 'Six', 'Seven'];
fixture.componentInstance.value = 'Seven';
fixture.detectChanges();
expect(fixture.componentInstance.toggleGroup.value).toBe('Seven');
expect(fixture.componentInstance.toggles.toArray()[2].checked).toBe(true);
});
});
@Component({
+11 -10
View File
@@ -95,10 +95,12 @@ export class MatButtonToggleGroup extends _MatButtonToggleGroupMixinBase impleme
private _selectionModel: SelectionModel<MatButtonToggle>;
/**
* Used for storing a value temporarily, if it is assigned
* before the button toggles are initialized.
* Reference to the raw value that the consumer tried to assign. The real
* value will exaclude any values from this one that don't correspond to a
* toggle. Useful for the cases where the value is assigned before the toggles
* have been initialized or at the same that they're being swapped out.
*/
private _tempValue: any;
private _rawValue: any;
/**
* The method to be called in order to update ngModel.
@@ -181,7 +183,6 @@ export class MatButtonToggleGroup extends _MatButtonToggleGroupMixinBase impleme
ngAfterContentInit() {
this._selectionModel.select(...this._buttonToggles.filter(toggle => toggle.checked));
this._tempValue = undefined;
}
/**
@@ -257,22 +258,22 @@ export class MatButtonToggleGroup extends _MatButtonToggleGroupMixinBase impleme
/** Determines whether a button toggle should be checked on init. */
_isPrechecked(toggle: MatButtonToggle) {
if (typeof this._tempValue === 'undefined') {
if (typeof this._rawValue === 'undefined') {
return false;
}
if (this.multiple && Array.isArray(this._tempValue)) {
return !!this._tempValue.find(value => toggle.value != null && value === toggle.value);
if (this.multiple && Array.isArray(this._rawValue)) {
return !!this._rawValue.find(value => toggle.value != null && value === toggle.value);
}
return toggle.value === this._tempValue;
return toggle.value === this._rawValue;
}
/** Updates the selection state of the toggles in the group based on a value. */
private _setSelectionByValue(value: any|any[]) {
// If the toggles haven't been initialized yet, save the value for later.
this._rawValue = value;
if (!this._buttonToggles) {
this._tempValue = value;
return;
}