diff --git a/packages/upgrade/src/common/util.ts b/packages/upgrade/src/common/util.ts index 849f6dd4dc..35dc83430f 100644 --- a/packages/upgrade/src/common/util.ts +++ b/packages/upgrade/src/common/util.ts @@ -90,6 +90,9 @@ export function hookupNgModel(ngModel: angular.INgModelController, component: an if (ngModel && supportsNgModel(component)) { ngModel.$render = () => { component.writeValue(ngModel.$viewValue); }; component.registerOnChange(ngModel.$setViewValue.bind(ngModel)); + if (typeof component.registerOnTouched === 'function') { + component.registerOnTouched(ngModel.$setTouched.bind(ngModel)); + } } } diff --git a/packages/upgrade/test/dynamic/upgrade_spec.ts b/packages/upgrade/test/dynamic/upgrade_spec.ts index 86837839c0..ff35abb500 100644 --- a/packages/upgrade/test/dynamic/upgrade_spec.ts +++ b/packages/upgrade/test/dynamic/upgrade_spec.ts @@ -478,9 +478,12 @@ export function main() { class Ng2 { private _value: any = ''; private _onChangeCallback: (_: any) => void = () => {}; + private _onTouchedCallback: () => void = () => {}; constructor() { ng2Instance = this; } writeValue(value: any) { this._value = value; } registerOnChange(fn: any) { this._onChangeCallback = fn; } + registerOnTouched(fn: any) { this._onTouchedCallback = fn; } + doTouch() { this._onTouchedCallback(); } doChange(newValue: string) { this._value = newValue; this._onChangeCallback(newValue); @@ -509,6 +512,13 @@ export function main() { expect($rootScope.modelA).toBe('C'); expect(multiTrim(document.body.textContent)).toEqual('C | C'); + const downgradedElement = document.body.querySelector('ng2'); + expect(downgradedElement.classList.contains('ng-touched')).toBe(false); + + ng2Instance.doTouch(); + $rootScope.$apply(); + expect(downgradedElement.classList.contains('ng-touched')).toBe(true); + ref.dispose(); }); })); diff --git a/packages/upgrade/test/static/integration/downgrade_component_spec.ts b/packages/upgrade/test/static/integration/downgrade_component_spec.ts index 12e674e7d9..496e7faf43 100644 --- a/packages/upgrade/test/static/integration/downgrade_component_spec.ts +++ b/packages/upgrade/test/static/integration/downgrade_component_spec.ts @@ -341,9 +341,12 @@ export function main() { class Ng2 { private _value: any = ''; private _onChangeCallback: (_: any) => void = () => {}; + private _onTouchedCallback: () => void = () => {}; constructor() { ng2Instance = this; } writeValue(value: any) { this._value = value; } registerOnChange(fn: any) { this._onChangeCallback = fn; } + registerOnTouched(fn: any) { this._onTouchedCallback = fn; } + doTouch() { this._onTouchedCallback(); } doChange(newValue: string) { this._value = newValue; this._onChangeCallback(newValue); @@ -374,6 +377,13 @@ export function main() { ng2Instance.doChange('C'); expect($rootScope.modelA).toBe('C'); expect(multiTrim(document.body.textContent)).toEqual('C | C'); + + const downgradedElement = document.body.querySelector('ng2'); + expect(downgradedElement.classList.contains('ng-touched')).toBe(false); + + ng2Instance.doTouch(); + $rootScope.$apply(); + expect(downgradedElement.classList.contains('ng-touched')).toBe(true); }); }));