diff --git a/src/lib/button-toggle/button-toggle.spec.ts b/src/lib/button-toggle/button-toggle.spec.ts
index ba34ae6fd28a..51d9390831c0 100644
--- a/src/lib/button-toggle/button-toggle.spec.ts
+++ b/src/lib/button-toggle/button-toggle.spec.ts
@@ -1,7 +1,7 @@
import {fakeAsync, tick, ComponentFixture, TestBed} from '@angular/core/testing';
import {dispatchMouseEvent} from '@angular/cdk/testing';
import {NgModel, FormsModule, ReactiveFormsModule, FormControl} from '@angular/forms';
-import {Component, DebugElement} from '@angular/core';
+import {Component, DebugElement, ViewChild, ViewChildren, QueryList} from '@angular/core';
import {By} from '@angular/platform-browser';
import {
MatButtonToggleGroup,
@@ -209,6 +209,7 @@ describe('MatButtonToggle without forms', () => {
StandaloneButtonToggle,
ButtonToggleWithAriaLabel,
ButtonToggleWithAriaLabelledby,
+ RepeatedButtonTogglesWithPreselectedValue,
],
});
@@ -662,6 +663,14 @@ describe('MatButtonToggle without forms', () => {
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
});
});
+
+ it('should not throw on init when toggles are repeated and there is an initial value', () => {
+ const fixture = TestBed.createComponent(RepeatedButtonTogglesWithPreselectedValue);
+
+ expect(() => fixture.detectChanges()).not.toThrow();
+ expect(fixture.componentInstance.toggleGroup.value).toBe('Two');
+ expect(fixture.componentInstance.toggles.toArray()[1].checked).toBe(true);
+ });
});
@Component({
@@ -759,3 +768,21 @@ class ButtonToggleWithAriaLabel { }
template: ``
})
class ButtonToggleWithAriaLabelledby {}
+
+
+@Component({
+ template: `
+
+
+ {{toggle}}
+
+
+ `
+})
+class RepeatedButtonTogglesWithPreselectedValue {
+ @ViewChild(MatButtonToggleGroup) toggleGroup: MatButtonToggleGroup;
+ @ViewChildren(MatButtonToggle) toggles: QueryList;
+
+ possibleValues = ['One', 'Two', 'Three'];
+ value = 'Two';
+}
diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts
index 5f83e66a72a6..bc4f600e9845 100644
--- a/src/lib/button-toggle/button-toggle.ts
+++ b/src/lib/button-toggle/button-toggle.ts
@@ -180,14 +180,8 @@ export class MatButtonToggleGroup extends _MatButtonToggleGroupMixinBase impleme
}
ngAfterContentInit() {
- // If there was an attempt to assign a value before init, use it to set the
- // initial selection, otherwise check the `checked` state of the toggles.
- if (typeof this._tempValue !== 'undefined') {
- this._setSelectionByValue(this._tempValue);
- this._tempValue = undefined;
- } else {
- this._selectionModel.select(...this._buttonToggles.filter(toggle => toggle.checked));
- }
+ this._selectionModel.select(...this._buttonToggles.filter(toggle => toggle.checked));
+ this._tempValue = undefined;
}
/**
@@ -261,6 +255,19 @@ export class MatButtonToggleGroup extends _MatButtonToggleGroupMixinBase impleme
return this._selectionModel.isSelected(toggle);
}
+ /** Determines whether a button toggle should be checked on init. */
+ _isPrechecked(toggle: MatButtonToggle) {
+ if (typeof this._tempValue === 'undefined') {
+ return false;
+ }
+
+ if (this.multiple && Array.isArray(this._tempValue)) {
+ return !!this._tempValue.find(value => toggle.value != null && value === toggle.value);
+ }
+
+ return toggle.value === this._tempValue;
+ }
+
/** 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.
@@ -409,6 +416,10 @@ export class MatButtonToggle extends _MatButtonToggleMixinBase implements OnInit
this.name = this.buttonToggleGroup.name;
}
+ if (this.buttonToggleGroup && this.buttonToggleGroup._isPrechecked(this)) {
+ this.checked = true;
+ }
+
this._focusMonitor.monitor(this._elementRef.nativeElement, true);
}
@@ -449,8 +460,8 @@ export class MatButtonToggle extends _MatButtonToggleMixinBase implements OnInit
* update bound properties of the radio button.
*/
_markForCheck() {
- // When group value changes, the button will not be notified. Use `markForCheck` to explicit
- // update button toggle's status
+ // When the group value changes, the button will not be notified.
+ // Use `markForCheck` to explicit update button toggle's status.
this._changeDetectorRef.markForCheck();
}
}