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

Commit e322cd9

Browse files
shahatapetebacondarwin
authored andcommitted
fix(ngModelOptions): do not trigger digest on setViewValue if debouncing
Note that this change means that anyone watching `$viewValue` will have to wait for a new digest before they are aware that it has been updated. Closes #8814 Closes #8850 Closes #8911
1 parent b3b6721 commit e322cd9

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

src/ng/directive/input.js

+11-19
Original file line numberDiff line numberDiff line change
@@ -958,13 +958,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
958958
// value, so it may be necessary to revalidate (by calling $setViewValue again) even if the
959959
// control's value is the same empty value twice in a row.
960960
if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
961-
if (scope.$root.$$phase) {
962-
ctrl.$setViewValue(value, event);
963-
} else {
964-
scope.$apply(function() {
965-
ctrl.$setViewValue(value, event);
966-
});
967-
}
961+
ctrl.$setViewValue(value, event);
968962
}
969963
};
970964

@@ -1218,9 +1212,7 @@ function radioInputType(scope, element, attr, ctrl) {
12181212

12191213
var listener = function(ev) {
12201214
if (element[0].checked) {
1221-
scope.$apply(function() {
1222-
ctrl.$setViewValue(attr.value, ev && ev.type);
1223-
});
1215+
ctrl.$setViewValue(attr.value, ev && ev.type);
12241216
}
12251217
};
12261218

@@ -1252,9 +1244,7 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
12521244
var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
12531245

12541246
var listener = function(ev) {
1255-
scope.$apply(function() {
1256-
ctrl.$setViewValue(element[0].checked, ev && ev.type);
1257-
});
1247+
ctrl.$setViewValue(element[0].checked, ev && ev.type);
12581248
};
12591249

12601250
element.on('click', listener);
@@ -1633,8 +1623,8 @@ var VALID_CLASS = 'ng-valid',
16331623
*
16341624
*
16351625
*/
1636-
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout',
1637-
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout) {
1626+
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope',
1627+
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope) {
16381628
this.$viewValue = Number.NaN;
16391629
this.$modelValue = Number.NaN;
16401630
this.$validators = {};
@@ -2157,8 +2147,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
21572147
pendingDebounce = $timeout(function() {
21582148
ctrl.$commitViewValue();
21592149
}, debounceDelay);
2160-
} else {
2150+
} else if ($rootScope.$$phase) {
21612151
ctrl.$commitViewValue();
2152+
} else {
2153+
$scope.$apply(function() {
2154+
ctrl.$commitViewValue();
2155+
});
21622156
}
21632157
};
21642158

@@ -2375,9 +2369,7 @@ var ngModelDirective = function() {
23752369
var modelCtrl = ctrls[0];
23762370
if (modelCtrl.$options && modelCtrl.$options.updateOn) {
23772371
element.on(modelCtrl.$options.updateOn, function(ev) {
2378-
scope.$apply(function() {
2379-
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
2380-
});
2372+
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
23812373
});
23822374
}
23832375

test/ng/directive/inputSpec.js

+16
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,22 @@ describe('input', function() {
14141414

14151415
}));
14161416

1417+
it('should not trigger digest while debouncing', inject(function($timeout) {
1418+
compileInput(
1419+
'<input type="text" ng-model="name" name="alias" '+
1420+
'ng-model-options="{ debounce: 10000 }"'+
1421+
'/>');
1422+
1423+
var watchSpy = jasmine.createSpy('watchSpy');
1424+
scope.$watch(watchSpy);
1425+
1426+
changeInputValueTo('a');
1427+
expect(watchSpy).not.toHaveBeenCalled();
1428+
1429+
$timeout.flush(10000);
1430+
expect(watchSpy).toHaveBeenCalled();
1431+
}));
1432+
14171433
it('should allow selecting different debounce timeouts for each event',
14181434
inject(function($timeout) {
14191435
compileInput(

0 commit comments

Comments
 (0)