Skip to content

Commit

Permalink
feat(ngModel) Allow running the formatters without a change to the mo…
Browse files Browse the repository at this point in the history
…delValue

Fixes angular#3407
  • Loading branch information
realityking committed Jan 17, 2015
1 parent 1a7e9de commit 2fa87c1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
38 changes: 26 additions & 12 deletions src/ng/directive/ngModel.js
Expand Up @@ -799,6 +799,28 @@ 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();
}
};

// model -> value
// Note: we cannot use a normal scope.$watch as we want to detect the following:
// 1. scope value is 'a'
Expand All @@ -814,19 +836,11 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
// TODO(perf): why not move this to the action fn?
if (modelValue !== ctrl.$modelValue) {
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
var oldViewValue = ctrl.$viewValue;

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();
if (ctrl.$viewValue !== oldViewValue) {
ctrl.$$runValidators(undefined, modelValue, ctrl.$viewValue, noop);
}
}

Expand Down
26 changes: 26 additions & 0 deletions test/ng/directive/ngModelSpec.js
Expand Up @@ -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();
});
});
});


Expand Down

0 comments on commit 2fa87c1

Please sign in to comment.