-->

Angular JS identify an digest complete event and r

2019-01-18 00:17发布

问题:

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.

Currently i am calling a method from the view

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.

回答1:

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.



回答2:

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