Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is $$phase in AngularJS?

Tags:

angularjs

I found this code snippet which is part of a angular directive someone wrote for bootstrap modal.

//Update the visible value when the dialog is closed                                                                                                                                                                                                                             //through UI actions (Ok, cancel, etc.)                                                                                                                                                                                                                                          element.bind("hide.bs.modal", function () {                                                                                                                                                                                                                                          scope.modalVisible = false;                                                                                                                                                                                                                                                      if (!scope.$$phase && !scope.$root.$$phase)                                                                                                                                                                                                                                          scope.$apply();                                                                                                                                                                                                                                                          });   

I understood that this part is for the latter half of two way binding we bind to hide.bs.modal event and update modal when UI changes.

I just wanted to know why is the person checking $$phase for scope and rootScope before calling apply ?

Can't we straightaway call apply ?

What is $$phase here?

I tried searching a lot, couldn't find any good explanation.

EDIT:

I found where I saw the example: Simple Angular Directive for Bootstrap Modal

like image 672
Amogh Talpallikar Avatar asked Nov 28 '13 10:11

Amogh Talpallikar


People also ask

What is $$ in AngularJS?

The $ in AngularJs is a built-in object.It contains application data and methods.

What is $Watch in AngularJS?

$watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in Angularjs to handle variable changes in application.

What is $scope in AngularJS?

The $scope in an AngularJS is a built-in object, which contains application data and methods. You can create properties to a $scope object inside a controller function and assign a value or function to it. The $scope is glue between a controller and view (HTML).

What is digest cycle in AngularJS?

Digest cycle is what Angular JS triggers when a value in the model or view is changed. The cycle sets off the watchers which then match the value of model and view to the newest value. Digest cycle automatically runs when the code encounters a directive.


2 Answers

$$phase is a flag set while angular is in a $digest cycle.

Sometimes (in rare cases), you want to check $$phase on the scope before doing an $apply. An error occurs if you try to $apply during a $digest:

Error: $apply already in progress

like image 163
Davin Tryon Avatar answered Oct 01 '22 23:10

Davin Tryon


Davin is totally correct that it's a flag that angular sets during the digest cycle.

But don't use it in your code.

I recently got a chance to ask Misko (angular author) about $$phase, and he said to never use it; it's an internal implementation of the digest cycle, and it's not future safe.

To make sure your code continues to work in the future, he suggested wrapping whatever you want to "safe apply" inside of a $timeout

$timeout(function() {   // anything you want can go here and will safely be run on the next digest. }) 

This comes up a lot when you have callbacks or other things that might resolve during the digest cycle (but don't always)

Here's an example snippet from when I was dealing with one of google's libraries: (The rest of the service this was from has been left off.)

window.gapi.client.load('oauth2', 'v2', function() {     var request = window.gapi.client.oauth2.userinfo.get();     request.execute(function(response) {         // This happens outside of angular land, so wrap it in a timeout          // with an implied apply and blammo, we're in action.         $timeout(function() {             if(typeof(response['error']) !== 'undefined'){                 // If the google api sent us an error, reject the promise.                 deferred.reject(response);             }else{                 // Resolve the promise with the whole response if ok.                 deferred.resolve(response);             }         });     }); }); 

Note that the delay argument for $timeout is optional and will default to 0 if left unset ($timeout calls $browser.defer which defaults to 0 if delay isn't set)

A little non-intuitive, but that's the answer from the guys writing Angular, so it's good enough for me!

like image 21
betaorbust Avatar answered Oct 01 '22 22:10

betaorbust