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 15, 2015
1 parent 1a7e9de commit 1329cb6
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
38 changes: 25 additions & 13 deletions src/ng/directive/ngModel.js
Expand Up @@ -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'
Expand All @@ -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;
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 1329cb6

Please sign in to comment.