aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ng/directive/input.js14
-rw-r--r--src/ngScenario/Scenario.js3
-rw-r--r--test/ng/directive/inputSpec.js17
3 files changed, 30 insertions, 4 deletions
diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
index 6a974d9d..c280b7c2 100644
--- a/src/ng/directive/input.js
+++ b/src/ng/directive/input.js
@@ -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);
+ });
+ }
}
};
diff --git a/src/ngScenario/Scenario.js b/src/ngScenario/Scenario.js
index 9a30d8a9..f323e01d 100644
--- a/src/ngScenario/Scenario.js
+++ b/src/ngScenario/Scenario.js
@@ -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 = [];
diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js
index 48319cfa..c9a345cd 100644
--- a/test/ng/directive/inputSpec.js
+++ b/test/ng/directive/inputSpec.js
@@ -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() {