diff --git a/modules/@angular/forms/src/directives/reactive_directives/form_control_directive.ts b/modules/@angular/forms/src/directives/reactive_directives/form_control_directive.ts index 9d7251c311..d7afecc64d 100644 --- a/modules/@angular/forms/src/directives/reactive_directives/form_control_directive.ts +++ b/modules/@angular/forms/src/directives/reactive_directives/form_control_directive.ts @@ -90,7 +90,9 @@ export class FormControlDirective extends NgControl implements OnChanges { ngOnChanges(changes: SimpleChanges): void { if (this._isControlChanged(changes)) { setUpControl(this.form, this); - if (this.control.disabled) this.valueAccessor.setDisabledState(true); + if (this.control.disabled && this.valueAccessor.setDisabledState) { + this.valueAccessor.setDisabledState(true); + } this.form.updateValueAndValidity({emitEvent: false}); } if (isPropertyUpdated(changes, this.viewModel)) { diff --git a/modules/@angular/forms/src/directives/reactive_directives/form_control_name.ts b/modules/@angular/forms/src/directives/reactive_directives/form_control_name.ts index d6bcacfa3d..2b4a29224b 100644 --- a/modules/@angular/forms/src/directives/reactive_directives/form_control_name.ts +++ b/modules/@angular/forms/src/directives/reactive_directives/form_control_name.ts @@ -152,7 +152,9 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy { private _setUpControl() { this._checkParentType(); this._control = this.formDirective.addControl(this); - if (this.control.disabled) this.valueAccessor.setDisabledState(true); + if (this.control.disabled && this.valueAccessor.setDisabledState) { + this.valueAccessor.setDisabledState(true); + } this._added = true; } } diff --git a/modules/@angular/forms/test/reactive_integration_spec.ts b/modules/@angular/forms/test/reactive_integration_spec.ts index 5d5af1a75d..c763d04c64 100644 --- a/modules/@angular/forms/test/reactive_integration_spec.ts +++ b/modules/@angular/forms/test/reactive_integration_spec.ts @@ -1025,7 +1025,7 @@ export function main() { }); describe('custom value accessors', () => { - it('should support custom value accessors', () => { + it('should support basic functionality', () => { const fixture = TestBed.createComponent(WrappedValueForm); const form = new FormGroup({'login': new FormControl('aa')}); fixture.componentInstance.form = form; @@ -1047,7 +1047,7 @@ export function main() { expect(form.get('login').errors).toEqual(null); }); - it('should support custom value accessors on non builtin input elements that fire a change event without a \'target\' property', + it('should support non builtin input elements that fire a change event without a \'target\' property', () => { const fixture = TestBed.createComponent(MyInputForm); fixture.componentInstance.form = new FormGroup({'login': new FormControl('aa')}); @@ -1063,6 +1063,27 @@ export function main() { input.componentInstance.dispatchChangeEvent(); }); + it('should support custom accessors without setDisabledState - formControlName', () => { + const fixture = TestBed.createComponent(WrappedValueForm); + fixture.componentInstance.form = new FormGroup({ + 'login': new FormControl({value: 'aa', disabled: true}), + }); + fixture.detectChanges(); + expect(fixture.componentInstance.form.status).toEqual('DISABLED'); + expect(fixture.componentInstance.form.get('login').status).toEqual('DISABLED'); + }); + + it('should support custom accessors without setDisabledState - formControlDirective', + () => { + TestBed.overrideComponent( + FormControlComp, + {set: {template: ``}}); + const fixture = TestBed.createComponent(FormControlComp); + fixture.componentInstance.control = new FormControl({value: 'aa', disabled: true}); + fixture.detectChanges(); + expect(fixture.componentInstance.control.status).toEqual('DISABLED'); + }); + }); });