fix(input): register builtin parsers/formatters before anyone else

Previously, builtin parsers/formatters for e.g. `input[date]`
or `input[number]` were added in the post linking phase to `ngModelController`,
which in most cases was after a custom formatter/parser was registered.

This commit registers builtin parsers/formatters already
in the pre linking phase. With that builtin
parsers run first, and builtin formatters run last.

Closes #9218
Closes #9358
This commit is contained in:
Tobias Bosch
2014-09-30 17:27:14 -07:00
parent a0bfdd0d60
commit 10644432ca
2 changed files with 84 additions and 9 deletions

View File

@@ -946,6 +946,69 @@ describe('ngModel', function() {
dealoc(element);
}));
describe('custom formatter and parser that are added by a directive in post linking', function() {
var inputElm, scope;
beforeEach(module(function($compileProvider) {
$compileProvider.directive('customFormat', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$formatters.push(function(value) {
return value.part;
});
ngModelCtrl.$parsers.push(function(value) {
return {part: value};
});
}
};
});
}));
afterEach(function() {
dealoc(inputElm);
});
function createInput(type) {
inject(function($compile, $rootScope) {
scope = $rootScope;
inputElm = $compile('<input type="'+type+'" ng-model="val" custom-format/>')($rootScope);
});
}
it('should use them after the builtin ones for text inputs', function() {
createInput('text');
scope.$apply('val = {part: "a"}');
expect(inputElm.val()).toBe('a');
inputElm.val('b');
browserTrigger(inputElm, 'change');
expect(scope.val).toEqual({part: 'b'});
});
it('should use them after the builtin ones for number inputs', function() {
createInput('number');
scope.$apply('val = {part: 1}');
expect(inputElm.val()).toBe('1');
inputElm.val('2');
browserTrigger(inputElm, 'change');
expect(scope.val).toEqual({part: 2});
});
it('should use them after the builtin ones for date inputs', function() {
createInput('date');
scope.$apply(function() {
scope.val = {part: new Date(2000, 10, 8)};
});
expect(inputElm.val()).toBe('2000-11-08');
inputElm.val('2001-12-09');
browserTrigger(inputElm, 'change');
expect(scope.val).toEqual({part: new Date(2001, 11, 9)});
});
});
it('should always format the viewValue as a string for a blank input type when the value is present',
inject(function($compile, $rootScope, $sniffer) {