Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop digest cycle manually in angularjs

Tags:

angularjs

As digest cycle do the dirty checking of the variable that is if there are 100 scope variables and if I change one variable then it will run watch of all the variables.

Suppose I have 100 scope model variables that are independent of each other. If I make changes in one variable then I don't want to check all other 99 variables. Is there any way to do this ? If yes, how ?

like image 751
Sunil Garg Avatar asked Jul 14 '16 18:07

Sunil Garg


People also ask

How do you trigger the digest cycle manually?

To answer your question, scope. $parent. $digest() will trigger a digest on scope 's parent.

How do you resolve $Digest already in progress?

There are a few ways to deal with this. The easiest way to deal with this is to use the built in $timeout, and a second way is if you are using underscore or lodash (and you should be), call the following: $timeout(function(){ //any code in here will automatically have an apply run afterwards });

What is the 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.

How are apply () Watch () Digest () different in AngularJS?

$apply() function will execute custom code and then it will call $scope. $digest() function forcefully to check all watch list variables and update variable values in view if any changes found for watch list variables. In most of the time angularjs will use $scope.


1 Answers

Surprisingly, this is usually not a problem, Browsers don’t have problems even with thousands of bindings, unless the expressions are complex. The common answer for how many watchers are ok to have is 2000.

Solutions :

It is fairly easy onwards from AngularJS 1.3, since one-time bindings are in core now.

  1. One time Binding of the variables.

We can use One time binding(::) directive to prevent the watcher to watch the unwanted variables. Here, variable will be watch only once & after that it will not update that variable.

  1. Stop the digest cycle manually.

HTML :

<ul ng-controller="myCtrl">
  <li ng-repeat="item in Lists">{{lots of bindings}}</li>
</ul>

Controller Code :

app.controller('myCtrl', function ($scope, $element) {
  $element.on('scroll', function () {
    $scope.Lists = getVisibleElements();
    $scope.$digest();
  });
});

During the $digest, you are only interested in changes to Lists object, not changes to individual items. Yet, Angular will still interrogate every single watcher for changes.

directive for stop and pause the digest:

app.directive('stopDigest', function () {
  return {
    link: function (scope) {
      var watchers;

      scope.$on('stop', function () {
        watchers = scope.$$watchers;
        scope.$$watchers = [];
      });

      scope.$on('resume', function () {
        if (watchers)
          scope.$$watchers = watchers;
      });
    }
  };
});

Now, Controller code should be changed :

<ul ng-controller="listCtrl">
  <li stop-digest ng-repeat="item in visibleList">{{lots of bindings}}</li>
</ul>

app.controller('myCtrl', function ($scope, $element) {
  $element.on('scroll', function () {
    $scope.visibleList = getVisibleElements();

    $scope.$broadcast('stop');
    $scope.$digest();
    $scope.$broadcast('resume');
  });
});

Reference Doc : https://coderwall.com/p/d_aisq/speeding-up-angularjs-s-digest-loop

Thanks.

like image 197
Creative Learner Avatar answered Oct 25 '22 08:10

Creative Learner