Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 1329cb6

Browse files
committed
feat(ngModel) Allow running the formatters without a change to the modelValue
Fixes #3407
1 parent 1a7e9de commit 1329cb6

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
lines changed

src/ng/directive/ngModel.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,30 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
799799
}
800800
};
801801

802+
function formatValue(modelValue) {
803+
var formatters = ctrl.$formatters,
804+
idx = formatters.length;
805+
806+
var viewValue = modelValue;
807+
while (idx--) {
808+
viewValue = formatters[idx](viewValue);
809+
}
810+
811+
return viewValue;
812+
}
813+
814+
this.$runFormatters = function() {
815+
var modelValue = this.$modelValue,
816+
viewValue = formatValue(this.$modelValue);
817+
818+
if (this.$viewValue !== viewValue) {
819+
this.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
820+
this.$render();
821+
822+
this.$$runValidators(undefined, modelValue, viewValue, noop);
823+
}
824+
};
825+
802826
// model -> value
803827
// Note: we cannot use a normal scope.$watch as we want to detect the following:
804828
// 1. scope value is 'a'
@@ -815,19 +839,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
815839
if (modelValue !== ctrl.$modelValue) {
816840
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
817841

818-
var formatters = ctrl.$formatters,
819-
idx = formatters.length;
820-
821-
var viewValue = modelValue;
822-
while (idx--) {
823-
viewValue = formatters[idx](viewValue);
824-
}
825-
if (ctrl.$viewValue !== viewValue) {
826-
ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
827-
ctrl.$render();
828-
829-
ctrl.$$runValidators(undefined, modelValue, viewValue, noop);
830-
}
842+
ctrl.$runFormatters();
831843
}
832844

833845
return modelValue;

test/ng/directive/ngModelSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,32 @@ describe('ngModel', function() {
578578

579579
dealoc(form);
580580
}));
581+
582+
describe('$runFormatters', function () {
583+
it('should reformat the value', function () {
584+
spyOn(ctrl, '$render');
585+
ctrl.$validators.spyValidator = jasmine.createSpy('spyValidator');
586+
scope.$apply('value = "first"');
587+
ctrl.$formatters.push(function(value) {
588+
return 'change';
589+
});
590+
ctrl.$runFormatters();
591+
expect(ctrl.$viewValue).toBe('change');
592+
});
593+
594+
it('should not rerender nor validate in case view value is not changed', function() {
595+
ctrl.$formatters.push(function(value) {
596+
return 'nochange';
597+
});
598+
599+
spyOn(ctrl, '$render');
600+
ctrl.$validators.spyValidator = jasmine.createSpy('spyValidator');
601+
scope.$apply('value = "first"');
602+
ctrl.$runFormatters();
603+
expect(ctrl.$validators.spyValidator).toHaveBeenCalledOnce();
604+
expect(ctrl.$render).toHaveBeenCalledOnce();
605+
});
606+
});
581607
});
582608

583609

0 commit comments

Comments
 (0)