From 48ce350fcfc3899f1e071d79a669aa80711de2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Thu, 15 Jan 2015 20:51:34 +0100 Subject: [PATCH] feat(ngModel) Allow running the formatters without a change to the modelValue Fix #3407 --- src/ng/directive/ngModel.js | 38 +++++++++++++++++++++----------- test/ng/directive/ngModelSpec.js | 26 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/ng/directive/ngModel.js b/src/ng/directive/ngModel.js index de1a5c491efa..6cf977f5bfd0 100644 --- a/src/ng/directive/ngModel.js +++ b/src/ng/directive/ngModel.js @@ -799,6 +799,30 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ } }; + function formatValue(modelValue) { + var formatters = ctrl.$formatters, + idx = formatters.length; + + var viewValue = modelValue; + while (idx--) { + viewValue = formatters[idx](viewValue); + } + + return viewValue; + } + + this.$runFormatters = function() { + var modelValue = this.$modelValue, + viewValue = formatValue(this.$modelValue); + + if (this.$viewValue !== viewValue) { + this.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; + this.$render(); + + this.$$runValidators(undefined, modelValue, viewValue, noop); + } + }; + // model -> value // Note: we cannot use a normal scope.$watch as we want to detect the following: // 1. scope value is 'a' @@ -815,19 +839,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ if (modelValue !== ctrl.$modelValue) { ctrl.$modelValue = ctrl.$$rawModelValue = modelValue; - var formatters = ctrl.$formatters, - idx = formatters.length; - - var viewValue = modelValue; - while (idx--) { - viewValue = formatters[idx](viewValue); - } - if (ctrl.$viewValue !== viewValue) { - ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; - ctrl.$render(); - - ctrl.$$runValidators(undefined, modelValue, viewValue, noop); - } + ctrl.$runFormatters(); } return modelValue; diff --git a/test/ng/directive/ngModelSpec.js b/test/ng/directive/ngModelSpec.js index 583414deaa9c..9f76902ad27e 100644 --- a/test/ng/directive/ngModelSpec.js +++ b/test/ng/directive/ngModelSpec.js @@ -578,6 +578,32 @@ describe('ngModel', function() { dealoc(form); })); + + describe('$runFormatters', function () { + it('should reformat the value', function () { + spyOn(ctrl, '$render'); + ctrl.$validators.spyValidator = jasmine.createSpy('spyValidator'); + scope.$apply('value = "first"'); + ctrl.$formatters.push(function(value) { + return 'change'; + }); + ctrl.$runFormatters(); + expect(ctrl.$viewValue).toBe('change'); + }); + + it('should not rerender nor validate in case view value is not changed', function() { + ctrl.$formatters.push(function(value) { + return 'nochange'; + }); + + spyOn(ctrl, '$render'); + ctrl.$validators.spyValidator = jasmine.createSpy('spyValidator'); + scope.$apply('value = "first"'); + ctrl.$runFormatters(); + expect(ctrl.$validators.spyValidator).toHaveBeenCalledOnce(); + expect(ctrl.$render).toHaveBeenCalledOnce(); + }); + }); });