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

Commit

Permalink
fix(ngModelOptions): do not trigger digest on setViewValue if debou…
Browse files Browse the repository at this point in the history
…ncing

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
  • Loading branch information
shahata authored and petebacondarwin committed Sep 5, 2014
1 parent b3b6721 commit e322cd9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 19 deletions.
30 changes: 11 additions & 19 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -958,13 +958,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
// value, so it may be necessary to revalidate (by calling $setViewValue again) even if the
// control's value is the same empty value twice in a row.
if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
if (scope.$root.$$phase) {
ctrl.$setViewValue(value, event);
} else {
scope.$apply(function() {
ctrl.$setViewValue(value, event);
});
}
ctrl.$setViewValue(value, event);
}
};

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

var listener = function(ev) {
if (element[0].checked) {
scope.$apply(function() {
ctrl.$setViewValue(attr.value, ev && ev.type);
});
ctrl.$setViewValue(attr.value, ev && ev.type);
}
};

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

var listener = function(ev) {
scope.$apply(function() {
ctrl.$setViewValue(element[0].checked, ev && ev.type);
});
ctrl.$setViewValue(element[0].checked, ev && ev.type);
};

element.on('click', listener);
Expand Down Expand Up @@ -1633,8 +1623,8 @@ var VALID_CLASS = 'ng-valid',
*
*
*/
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout',
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout) {
var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope',
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope) {
this.$viewValue = Number.NaN;
this.$modelValue = Number.NaN;
this.$validators = {};
Expand Down Expand Up @@ -2157,8 +2147,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
pendingDebounce = $timeout(function() {
ctrl.$commitViewValue();
}, debounceDelay);
} else {
} else if ($rootScope.$$phase) {
ctrl.$commitViewValue();
} else {
$scope.$apply(function() {
ctrl.$commitViewValue();
});
}
};

Expand Down Expand Up @@ -2375,9 +2369,7 @@ var ngModelDirective = function() {
var modelCtrl = ctrls[0];
if (modelCtrl.$options && modelCtrl.$options.updateOn) {
element.on(modelCtrl.$options.updateOn, function(ev) {
scope.$apply(function() {
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
});
modelCtrl.$$debounceViewValueCommit(ev && ev.type);
});
}

Expand Down
16 changes: 16 additions & 0 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,22 @@ describe('input', function() {

}));

it('should not trigger digest while debouncing', inject(function($timeout) {
compileInput(
'<input type="text" ng-model="name" name="alias" '+
'ng-model-options="{ debounce: 10000 }"'+
'/>');

var watchSpy = jasmine.createSpy('watchSpy');
scope.$watch(watchSpy);

changeInputValueTo('a');
expect(watchSpy).not.toHaveBeenCalled();

$timeout.flush(10000);
expect(watchSpy).toHaveBeenCalled();
}));

it('should allow selecting different debounce timeouts for each event',
inject(function($timeout) {
compileInput(
Expand Down

0 comments on commit e322cd9

Please sign in to comment.