Angular JS identify an digest complete event and removing # from url in angular js during viewchange
Asked Answered
M

2

7

1) Is there any digest complete event which I can use to update my canvas. I have an angular app which has view for different properties of the canvas object. Whenever I change the property, once the digest is complete, If I can get the digest complete event I can update the canvas(using kineticJs) to redraw the chart with latest properties.

Popup view and Canvas

Currently i am calling a method from the view

enter image description here

2) I am just using views and routing it to a new view whenever an object settings is opened. In this case the url also change with the webpage/#view.Its just the popup I dont need the #view at the end of the page but to still use the routing and view concept. Is there any otherway.

Moyna answered 15/1, 2014 at 13:14 Comment(2)
Is just watching the properties not good enough?Lucchesi
I can imagine that you want this for performance reasons, eg only redraw when everything has settled down.Solanum
S
24

Update

Karl seamon gave a talk in ng-conf 2014.

In this video (22:20 minute) he talked about a future possiblity of a built-in $postDigestWatch.

Here is an open issue in: https://github.com/angular/angular.js/issues/5828

So, It will probably get to the core in future releases, until then you can use the trick below.


An example on plunker.

  • A digest cycle may have multiple $digest.
  • I $watch for the first $digest to register a $timeout which would run after the digest cycle ends.
  • I must unregister the $watch immediately to avoid multiple $timeout callbacks for one digest cycle.
  • In the $timeout callback I invoke the user callback and register a $watch for the next $digest.

Use $watch in conjunction with $timeout:

function postDigest(callback){    
  var unregister = $rootScope.$watch(function(){  
    unregister();
    $timeout(function(){
      callback();
      postDigest(callback);
    },0,false);       
  });
}

postDigest(function(){
  console.log('do something');
})

$digest ,From the docs:

If you want to be notified whenever $digest() is called, you can register a watchExpression function with $watch() with no listener.

$timeout , From here: Defer angularjs watch execution after $digest (raising DOM event)

$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.

Slowpoke answered 15/1, 2014 at 13:20 Comment(4)
That will call the provided function on every digest. It does not inform you if a digest has been completed.Solanum
I updated the answer so it will only run once after a digest cycleSlowpoke
If the current digest triggers another digest (eg changes a value on any scope) the postDigest is called every time (not when the digest has settled).Solanum
The $timeout callback is invoked only once after a digest cycle therefore postDigest would be called only once after a digest cycle.Slowpoke
J
0

as an alternative to what Ilan said, you could use $evalAsync.

from the same docs:

Executes the expression on the current scope at a later point in time.

The $evalAsync makes no guarantees as to when the expression will be executed, only that:

it will execute after the function that scheduled the evaluation (preferably before DOM rendering).
at least one $digest cycle will be performed after expression execution.
Any exceptions from the execution of the expression are forwarded to the $exceptionHandler service.

Note: if this function is called outside of a $digest cycle, a new $digest cycle will be scheduled. However, it is encouraged to always call code that changes the model from within an $apply call. That includes code evaluated via $evalAsync

Also, take a look at this comment in regards to this

Jacobba answered 15/1, 2014 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.