mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix(input): prevent double $digest when using jQuery trigger.
If an event was performed natively, jQuery sets the isTrigger property. When triggering event manually, the field is not present. Manually triggered events are performed synchronously which causes the "$digest already in progress" error. Closes #5293
This commit is contained in:
parent
bddd46c8ec
commit
1147f21999
3 changed files with 30 additions and 4 deletions
|
|
@ -407,7 +407,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|||
});
|
||||
}
|
||||
|
||||
var listener = function() {
|
||||
var listener = function(ev) {
|
||||
if (composing) return;
|
||||
var value = element.val();
|
||||
|
||||
|
|
@ -419,9 +419,17 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|||
}
|
||||
|
||||
if (ctrl.$viewValue !== value) {
|
||||
scope.$apply(function() {
|
||||
// If an event was performed natively, jQuery sets the isTrigger property.
|
||||
// When triggering event manually, the field is not present. Manually
|
||||
// triggered events are performed synchronously which causes the "$digest
|
||||
// already in progress" error.
|
||||
if (ev && ev.isTrigger) {
|
||||
ctrl.$setViewValue(value);
|
||||
});
|
||||
} else {
|
||||
scope.$apply(function() {
|
||||
ctrl.$setViewValue(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,8 @@ function callerFile(offset) {
|
|||
* To work around this we instead use our own handler that fires a real event.
|
||||
*/
|
||||
(function(fn){
|
||||
var parentTrigger = fn.trigger;
|
||||
// We need a handle to the original trigger function for input tests.
|
||||
var parentTrigger = fn._originalTrigger = fn.trigger;
|
||||
fn.trigger = function(type) {
|
||||
if (/(click|change|keydown|blur|input|mousedown|mouseup)/.test(type)) {
|
||||
var processDefaults = [];
|
||||
|
|
|
|||
|
|
@ -533,6 +533,23 @@ describe('input', function() {
|
|||
'event so that form auto complete works',function() {
|
||||
assertBrowserSupportsChangeEvent(true);
|
||||
});
|
||||
|
||||
if (!_jqLiteMode) {
|
||||
it('should not cause the double $digest when triggering an event using jQuery', function() {
|
||||
$sniffer.hasEvent = function(eventName) {
|
||||
return eventName !== 'input';
|
||||
};
|
||||
|
||||
compileInput('<input type="text" ng-model="name" name="alias" ng-change="change()" />');
|
||||
|
||||
scope.field = 'fake field';
|
||||
scope.$watch('field', function() {
|
||||
// We need to use _originalTrigger since trigger is modified by Angular Scenario.
|
||||
inputElm._originalTrigger('change');
|
||||
});
|
||||
scope.$apply();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('"paste" and "cut" events', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue