I have a watch that triggers a DOM event:
scope.$watch(function() { return controller.selected; }, function(selected) {
if (selected) {
$input.trigger('focus');
}
});
The issue is that I have a handler on 'focus' that does a scope.$apply
.
$input.bind('focus', function() {
scope.$apply(function() { controller.focused = true; });
});
So when my $watch
is fired from inside a $digest
it causes an error because it tries to trigger another $digest
.
The workaround I have is to put the trigger in a $timeout
.
scope.$watch(function() { return controller.selected; }, function(selected) {
if (selected) {
$timeout(function() { $input.trigger('focus'); });
}
});
This works ... so far. Is this the proper way to handle this? I'm not sure if this catches every case and would like to see if there is an angular approved way to have a piece of code defer for after the digest.
Thanks!
$timeout is normally what is used to run something after a digest cycle (and after the browser renders).
$timeout
will cause another digest cycle to be executed after the function is executed. If your trigger
does not affect anything Angular, you can set the invokeApply
argument to false
to avoid running another digest cycle.
If you want your callback to run before the browser renders: If code is queued using $evalAsync
from a directive, it should run after the DOM has been manipulated by Angular, but before the browser renders. However, if code is queued using $evalAsync
from a controller, it will run before the DOM has been manipulated by Angular (and before the browser renders). See also https://stackoverflow.com/a/17303759/215945.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With