Skip to content

Commit 02e1c57

Browse files
committed
fix(select): disabled state out of sync when swapping form group with a disabled one
Fixes the disabled state of a `mat-select` falling out of sync with its form control if the control's group is swapped out with one that is disabled on init. Fixes #17860.
1 parent 49b6dbd commit 02e1c57

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/material/select/select.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
NG_VALUE_ACCESSOR,
4949
ReactiveFormsModule,
5050
Validators,
51+
FormBuilder,
5152
} from '@angular/forms';
5253
import {
5354
ErrorStateMatcher,
@@ -128,6 +129,7 @@ describe('MatSelect', () => {
128129
SelectWithGroupsAndNgContainer,
129130
SelectWithFormFieldLabel,
130131
SelectWithChangeEvent,
132+
SelectInsideDynamicFormGroup,
131133
]);
132134
}));
133135

@@ -1903,6 +1905,20 @@ describe('MatSelect', () => {
19031905
expect(fixture.componentInstance.select.panelOpen)
19041906
.toBe(true, `Expected select panelOpen property to become true.`);
19051907
}));
1908+
1909+
it('should keep the disabled state in sync if the form group is swapped and ' +
1910+
'disabled at the same time', fakeAsync(() => {
1911+
const fixture = TestBed.createComponent(SelectInsideDynamicFormGroup);
1912+
const instance = fixture.componentInstance;
1913+
fixture.detectChanges();
1914+
1915+
expect(instance.select.disabled).toBe(false);
1916+
1917+
instance.assignGroup(true);
1918+
fixture.detectChanges();
1919+
1920+
expect(instance.select.disabled).toBe(true);
1921+
}));
19061922
});
19071923

19081924
describe('animations', () => {
@@ -5267,3 +5283,30 @@ class MultiSelectWithLotsOfOptions {
52675283
this.value = [];
52685284
}
52695285
}
5286+
5287+
5288+
@Component({
5289+
template: `
5290+
<form [formGroup]="form">
5291+
<mat-form-field>
5292+
<mat-select formControlName="control">
5293+
<mat-option value="1">One</mat-option>
5294+
</mat-select>
5295+
</mat-form-field>
5296+
</form>
5297+
`
5298+
})
5299+
class SelectInsideDynamicFormGroup {
5300+
@ViewChild(MatSelect) select: MatSelect;
5301+
form: FormGroup;
5302+
5303+
constructor(private _formBuilder: FormBuilder) {
5304+
this.assignGroup(false);
5305+
}
5306+
5307+
assignGroup(isDisabled: boolean) {
5308+
this.form = this._formBuilder.group({
5309+
control: {value: '', disabled: isDisabled}
5310+
});
5311+
}
5312+
}

src/material/select/select.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
566566

567567
ngDoCheck() {
568568
if (this.ngControl) {
569+
// The disabled state might go out of sync if the form group is swapped out. See #17860.
570+
if (this.ngControl.disabled !== this.disabled) {
571+
this.disabled = !!this.ngControl.disabled;
572+
}
573+
569574
this.updateErrorState();
570575
}
571576
}

0 commit comments

Comments
 (0)