From cb540c71a76dba6285ad05e582781a04816d573b Mon Sep 17 00:00:00 2001 From: AlexChan Date: Tue, 28 Oct 2014 00:50:15 +0100 Subject: [PATCH 1/3] fix:(input) asynchronous ng-model blur If the model is blurred during an apply it should trigger the $touched asynchronously. Fixes https://github.com/angular/angular.js/issues/8762 --- src/ng/directive/input.js | 11 ++++++++--- test/ng/directive/inputSpec.js | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 9bd6dc979ab6..28bc85625517 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -2460,9 +2460,14 @@ var ngModelDirective = function() { element.on('blur', function(ev) { if (modelCtrl.$touched) return; - scope.$apply(function() { - modelCtrl.$setTouched(); - }); + var onBlurSetTouched = function() { + modelCtrl.$setTouched(); + }; + if (scope.$$phase) { + scope.$evalAsync(onBlurSetTouched); + } else { + scope.$apply(onBlurSetTouched); + } }); } }; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 8d4e47763609..09e09e262964 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -1144,6 +1144,32 @@ describe('ngModel', function() { dealoc(element); })); + it('should digest asynchronously on "blur" event if a apply is already in progress', + inject(function($compile, $rootScope) { + + var element = $compile('
' + + '' + + '
')($rootScope); + var inputElm = element.find('input'); + var control = $rootScope.myForm.myControl; + + $rootScope.$apply(function() { + expect(control.$touched).toBe(false); + expect(control.$untouched).toBe(true); + + browserTrigger(inputElm, 'blur'); + + expect(control.$touched).toBe(false); + expect(control.$untouched).toBe(true); + }); + + expect(control.$touched).toBe(true); + expect(control.$untouched).toBe(false); + + dealoc(element); + })); + + it('should register/deregister a nested ngModel with parent form when entering or leaving DOM', inject(function($compile, $rootScope) { From b0821af4af4516457686d3970bef2bb9c7838862 Mon Sep 17 00:00:00 2001 From: AlexChan Date: Tue, 28 Oct 2014 01:00:05 +0100 Subject: [PATCH 2/3] Directly call $setTouched --- src/ng/directive/input.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 28bc85625517..7995dd7e9a21 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -2459,14 +2459,10 @@ var ngModelDirective = function() { element.on('blur', function(ev) { if (modelCtrl.$touched) return; - - var onBlurSetTouched = function() { - modelCtrl.$setTouched(); - }; if (scope.$$phase) { - scope.$evalAsync(onBlurSetTouched); + scope.$evalAsync(modelCtrl.$setTouched); } else { - scope.$apply(onBlurSetTouched); + scope.$apply(modelCtrl.$setTouched); } }); } From cd435cad42f0e3f469f55322f0ad9183d4398da8 Mon Sep 17 00:00:00 2001 From: AlexChan Date: Tue, 28 Oct 2014 21:22:37 +0100 Subject: [PATCH 3/3] use .18397phase --- src/ng/directive/input.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 7995dd7e9a21..8c2c220148e1 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -2416,7 +2416,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * */ -var ngModelDirective = function() { +var ngModelDirective = ['$rootScope', function($rootScope) { return { restrict: 'A', require: ['ngModel', '^?form', '^?ngModelOptions'], @@ -2459,7 +2459,8 @@ var ngModelDirective = function() { element.on('blur', function(ev) { if (modelCtrl.$touched) return; - if (scope.$$phase) { + + if ($rootScope.$$phase) { scope.$evalAsync(modelCtrl.$setTouched); } else { scope.$apply(modelCtrl.$setTouched); @@ -2469,7 +2470,7 @@ var ngModelDirective = function() { }; } }; -}; +}]; /**