9

We have a large model and it takes a couple seconds for ng-repeat to bind all the items in the model to the form. We would like to show a spinner while it this is happening. Is there some event that fires when binding is complete so we know when to hide the spinner?

adam0101
  • 29,096
  • 21
  • 96
  • 174
  • 3
    http://stackoverflow.com/questions/13471129/angularjs-ng-repeat-finish-event is this what you're looking for? I didn't flag as duplicate because I don't know enough about Angular to make that call. Hope this helps you though. – Ricky Mutschlechner Nov 08 '13 at 16:31
  • I'm no angularjs expert, but the binding should be a syncronous operation. Show the spinner before the call, hide it after: no need to use callbacks. – Saturnix Nov 08 '13 at 16:32

4 Answers4

11

Plunkr: http://plnkr.co/edit/GzzTW4?p=preview

Use ng-show on the spinner If you are using 1.2 use ng-if

<div ng-controller="Ctrl">
    <div ng-show="complete">Complete={{complete}}</div>
    <div class="thing" ng-repeat="thing in things" my-post-repeat-directive>
       thing {{thing}}
   </div>
</div>

In your directive use $last to determine if rendering is done and then change the variable that you have the ng-show/ngif defined on.

function Ctrl($scope) {
  $scope.complete=false;  
  $scope.doComplete = function() {
      $scope.complete = true;
  }

  $scope.things = [
    'A', 'B', 'C'
  ];
}

angular.module('myApp', [])
  .directive('myPostRepeatDirective', function() {
    return function(scope, element, attrs) {
      if (scope.$last) {
        scope.$eval('doComplete()');
      }
    };
  });
Nathaniel Johnson
  • 4,731
  • 1
  • 42
  • 69
2

You can watch for $last item compile/link function, and fire a custom event to the scope

doodeec
  • 2,927
  • 19
  • 23
2

In that kind of situations, I use the $timeout service mixed with the $viewContentLoaded event fired by angular ui router (if you use ui router) :

about $timeout :

This service is just a simple decorator for $timeout service that adds a "flush" and "verifyNoPendingTasks" methods.

about $viewContentLoaded

fired once the view is loaded, after the DOM is rendered. The '$scope' of the view emits the event.

My personal usecase is for a paymentForm to dynamically generate its hidden inputs (using HTML data computed serverside that I insert through ng-bind-html) and submit to the payment Gateway :

$scope.$on('$viewContentLoaded', function() { 
    $timeout(function () {
        $scope.paymentForm.submit();
    });
});

FYI in the above code example, .submit() is a function from a custom directive used with the form in order to be able to autosubmit the form.

Julien

Julien L
  • 53
  • 5
-1

For this I normally create a spinner div in your view with an ng-show="submitting". Then when the data is loaded, you set the $scope.submitting to 'false' show the spinner is hidden.

<!-- In your HTML -->
<div class="spinner" ng-show="submitting">
<div ng-repeat="p in people">
   {{p.name}}
</div>

//In Javascript
$scope.submitting = true;
$scope.load_data = function(){
    $http.get('/api/route')
        .then(function(success){
            $scope.submitting = false;
        },function(error){
            console.log(error);
        });
}

I hope that helps

mylescc
  • 5,720
  • 3
  • 17
  • 23
  • 1
    I think the question is not so much about showing the spinner during a service call but during the processing of a large ng-repeat array. – Nathaniel Johnson Nov 08 '13 at 16:38