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

(Implicitly) triggering browser events from Angular event handlers #1342

Closed
mprobst opened this issue Sep 7, 2012 · 2 comments
Closed

(Implicitly) triggering browser events from Angular event handlers #1342

mprobst opened this issue Sep 7, 2012 · 2 comments

Comments

@mprobst
Copy link
Contributor

mprobst commented Sep 7, 2012

Imagine an Angular event handler, eg. an ng-click handler, that wants to focus a particular text field (probably as part of a directive, not in the controller itself):

function handleClick() {
someNode.focus();
}

Now the focus triggers an onFocus event by itself, which if listened to will likely trigger a scope.$apply. Because we're already in a digest cycle, this will trigger an error ('digest already in progress').

Currently the only way out of that is going asynchronous via $timeout. That makes testing much harder, causes another unnecessary cycle immediately after the current, and also turns a detectable loop condition ('more than XXX digest iterations') into a possible infinite 100% CPU loop.

It would be nice if there was an API to detect the condition, or to say "$apply within the current cycle, and trigger one if not already in progress".

@vojtajina
Copy link
Contributor

I think when doing elm.focus() you need to use setTimeout / $timeout anyway, otherwise it might not get focused.
You can use $timeout(fn, 0, false) that won't cause $apply.

You can check, whether $apply is in progress, just do:
if (!scope.$root.$$phase) scope.$apply();

@pkozlowski-opensource
Copy link
Member

This is the same issue as #1250

Let's tackle focus setting in #2012

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants