1

Hey guys so I have the following predigament:

I have an ng-repeat with another ng-repeat with another ng-repeat and so forth ( creating something similar of a binary tree structure but with multiple roots). The problem is that my data is inserted into the proper structures and is waiting for the digest to actually display everything on the screen since some of the structures are quite large. How can I know when digest has finished rendering the last of the elements of my structure? I have the following added to my ng-repeates but that gets executed so many times because ng-repeats can also be ng-repeated... How can I only signal when the last of the templates has loaded and not every time a template loads? Here is what I have thanks to another thread Calling a function when ng-repeat has finished:

app.directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});


app.directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});

Problem is that this fires for the last ng-repeat but I cannot determined when the last of the nested ng-repeates finishes.. Is there any way to detect that the digest has finished rendering all of my templates and nested templates?

Community
  • 1
  • 1
Georgi Angelov
  • 4,338
  • 12
  • 67
  • 96

1 Answers1

1

Normally this would just be handled by watching for $scope.$last in your specific repeat.

However, if we are loading up a lot of data at runtime execution, perhaps Angular $postDigest to the rescue!

P.S. Don't use $emit in this case. Remember that directives can link with any scope you need in any controller and modify their value, and that overall - using $emit or $broadcast should always be avoided unless absolutely necessary.

app.directive('resolveApplication', function($timeout) {
    return {
        restrict:'A',
        link: function (scope) {
            // start by waiting for digests to finish
            scope.$$postDigest(function() {
                // next we wait for the dom to be ready
                angular.element(document).ready(function () {
                    // finally we apply a timeout with a value
                    // of 0 ms to allow any lingering js threads
                    // to catch up
                    $timeout(function() {
                        // your dom is ready and rendered
                        // if you have an ng-show wrapper 
                        // hiding your view from the ugly 
                        // render cycle, we can go ahead 
                        // and unveil that now:
                        scope.ngRepeatFinished = true;
                    },0)
                });
            });
        }
    } 
});
DrewT
  • 4,983
  • 2
  • 40
  • 53