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

Commit 1060991

Browse files
feat($ngModelOptions): add new service to support the ngModelOptions directive
1 parent 0c24058 commit 1060991

File tree

3 files changed

+64
-13
lines changed

3 files changed

+64
-13
lines changed

src/AngularPublic.js

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
$HttpBackendProvider,
7070
$LocationProvider,
7171
$LogProvider,
72+
$ModelOptionsProvider,
7273
$ParseProvider,
7374
$RootScopeProvider,
7475
$QProvider,
@@ -224,6 +225,7 @@ function publishExternalAPI(angular) {
224225
$httpBackend: $HttpBackendProvider,
225226
$location: $LocationProvider,
226227
$log: $LogProvider,
228+
$modelOptions: $ModelOptionsProvider,
227229
$parse: $ParseProvider,
228230
$rootScope: $RootScopeProvider,
229231
$q: $QProvider,

src/ng/directive/input.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ function createDateInputType(type, regexp, parseDate, format) {
11451145
return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
11461146
badInputChecker(scope, element, attr, ctrl);
11471147
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
1148-
var timezone = ctrl && ctrl.$options && ctrl.$options.timezone;
1148+
var timezone = ctrl && ctrl.$options.timezone;
11491149
var previousDate;
11501150

11511151
ctrl.$$parserName = type;

src/ng/directive/ngModel.js

+61-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
DIRTY_CLASS: true,
77
UNTOUCHED_CLASS: true,
88
TOUCHED_CLASS: true,
9+
$ModelOptionsProvider: true,
910
*/
1011

1112
var VALID_CLASS = 'ng-valid',
@@ -217,8 +218,8 @@ is set to `true`. The parse error is stored in `ngModel.$error.parse`.
217218
*
218219
*
219220
*/
220-
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope', '$q', '$interpolate',
221-
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) {
221+
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope', '$q', '$interpolate', '$modelOptions',
222+
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate, $modelOptions) {
222223
this.$viewValue = Number.NaN;
223224
this.$modelValue = Number.NaN;
224225
this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
@@ -237,7 +238,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
237238
this.$$success = {}; // keep valid keys here
238239
this.$pending = undefined; // keep pending keys here
239240
this.$name = $interpolate($attr.name || '', false)($scope);
240-
241+
this.$options = $modelOptions.defaultOptions;
241242

242243
var parsedNgModel = $parse($attr.ngModel),
243244
parsedNgModelAssign = parsedNgModel.assign,
@@ -246,9 +247,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
246247
pendingDebounce = null,
247248
ctrl = this;
248249

249-
this.$$setOptions = function(options) {
250-
ctrl.$options = options;
251-
if (options && options.getterSetter) {
250+
251+
this.$$initGetterSetters = function() {
252+
253+
if (ctrl.$options.getterSetter) {
252254
var invokeModelGetter = $parse($attr.ngModel + '()'),
253255
invokeModelSetter = $parse($attr.ngModel + '($$$p)');
254256

@@ -272,6 +274,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
272274
}
273275
};
274276

277+
275278
/**
276279
* @ngdoc method
277280
* @name ngModel.NgModelController#$render
@@ -523,7 +526,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
523526
var prevValid = ctrl.$valid;
524527
var prevModelValue = ctrl.$modelValue;
525528

526-
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
529+
var allowInvalid = ctrl.$options.allowInvalid;
527530

528531
ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
529532
// If there was no change in validity, don't update the model
@@ -683,7 +686,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
683686
ctrl.$modelValue = ngModelGet($scope);
684687
}
685688
var prevModelValue = ctrl.$modelValue;
686-
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
689+
var allowInvalid = ctrl.$options.allowInvalid;
687690
ctrl.$$rawModelValue = modelValue;
688691

689692
if (allowInvalid) {
@@ -764,7 +767,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
764767
*/
765768
this.$setViewValue = function(value, trigger) {
766769
ctrl.$viewValue = value;
767-
if (!ctrl.$options || ctrl.$options.updateOnDefault) {
770+
if (ctrl.$options.updateOnDefault) {
768771
ctrl.$$debounceViewValueCommit(trigger);
769772
}
770773
};
@@ -774,7 +777,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
774777
options = ctrl.$options,
775778
debounce;
776779

777-
if (options && isDefined(options.debounce)) {
780+
if (isDefined(options.debounce)) {
778781
debounce = options.debounce;
779782
if (isNumber(debounce)) {
780783
debounceDelay = debounce;
@@ -1016,7 +1019,11 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
10161019
var modelCtrl = ctrls[0],
10171020
formCtrl = ctrls[1] || nullFormCtrl;
10181021

1019-
modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options);
1022+
if (ctrls[2]) {
1023+
modelCtrl.$options = ctrls[2].$options;
1024+
}
1025+
1026+
modelCtrl.$$initGetterSetters();
10201027

10211028
// notify others, especially parent forms
10221029
formCtrl.$addControl(modelCtrl);
@@ -1033,7 +1040,7 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
10331040
},
10341041
post: function ngModelPostLink(scope, element, attr, ctrls) {
10351042
var modelCtrl = ctrls[0];
1036-
if (modelCtrl.$options && modelCtrl.$options.updateOn) {
1043+
if (modelCtrl.$options.updateOn) {
10371044
element.on(modelCtrl.$options.updateOn, function(ev) {
10381045
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
10391046
});
@@ -1396,3 +1403,45 @@ function isObjectEmpty(obj) {
13961403
}
13971404
return true;
13981405
}
1406+
1407+
1408+
1409+
/**
1410+
* @ngdoc service
1411+
* @name $modelOptions
1412+
* @description
1413+
* This service provides support to the ngModelOptions directive.
1414+
*
1415+
* You can register default options that are used application wide if no ngModelOptions
1416+
* directive is found.
1417+
*
1418+
* You can register model adaptors that can selected by ngModelOptions settings to modify
1419+
* the behavior of ngModel, form and input directives.
1420+
*/
1421+
function $ModelOptionsProvider() {
1422+
return {
1423+
$get: function() {
1424+
return {
1425+
/**
1426+
* @ngdoc property
1427+
* @name $modelOptions#defaultOptions
1428+
* @type {Object}
1429+
* @description
1430+
* The default options to fall back on when there are no more ngModelOption
1431+
* directives as ancestors
1432+
*/
1433+
defaultOptions: {
1434+
updateOnDefault: true
1435+
},
1436+
/**
1437+
* @ngdoc property
1438+
* @name $modelOptions#modelAdaptors
1439+
* @type {Object<string, Function>}
1440+
* @description
1441+
* The functions that adapt the behaviour of ngModel
1442+
*/
1443+
modelAdaptors: {}
1444+
};
1445+
}
1446+
};
1447+
};

0 commit comments

Comments
 (0)