2
votes

I have tried all three terms for refreshing the scope after triggering any event. Sometimes I got an error

$apply or $digest is already in progress.

Finally I am using $timeout without any error. But I don't know that which one is best as per the complexity or performance.

1
Performance is a very broad topic. For example checking if the digest is running and calling it if it isn't is probably most performant (digest and apply are fairly similar). But I always use timeouts because they are easier and seem to be less erratic.Jackie
on my view $timout is the best approachfelipekm
You shouldn't have to call any of them to react to an event. Just use the appropriate ng-xxx directive.JB Nizet
"JB Nizet: sometimes it's very important to call any of them for refreshing the scope or rootscope for our own custom directive and including javascript code in angular.Kishan Kumar Soni
Then give a concrete example. In 99% of the cases, it's not necessary. If you need to use it often, then you're doing something wrong. And if you get an error message when you're doing it, that means you should NOT use it, and don't really understand what you're doing. Without a concrete example, we can't help. As it's often the case with people here, you wonder about performance before even thinking about correctness. If you get errors, you should strive to understand why you get them, and how to avoid them. The performance should be the least of your concerns.JB Nizet

1 Answers

1
votes

$timeout calls $apply which calls $digest.

In more detail:

$apply triggers a $digest cycle on root scope (therefore on all scopes within the application).

$digest can be called directly on a particular child scope instead of on root -- but watchers on parent or sibling scopes won't be triggered, so incautious use of $digest can leave different scopes visibly out of synch.

$timeout waits for the next digest cycle, and then calls $apply (and thus is basically a simple way to call $apply without worrying about "digest already in progress" errors.) The newer $evalAsync is similar but applies to the current digest if possible, so is sometimes slightly more performant than $timeout. (There is also $applyAsync which is as far as I can tell basically $timeout with a 10ms delay, for reasons which I'm sure make sense to someone.)

TL;DR: leave Angular to manage its own data lifecycle as much as possible. When you need to, use $evalAsync (or, honestly, $timeout is close enough; the difference is not that significant).

If you start running into performance issues, you can start looking for cases where you can safely switch to using $digest on specific scopes. (Personally I've not seen many cases where this is worth the added code complexity, but maybe that's just me.)