0

I got some trouble understanding how I make a callback after I've updated an ng-repeat. I basically want to be able to make a callback function after my updates to my ng-repeat has been finished. Currently have this:

var app = angular.module('myApp', []);

app.directive('onLastRepeat', function() {
    return function(scope, element, attrs) {
        if (scope.$first)
           console.log("ng-repeat starting - Index: " + scope.$index) 
        if (scope.$last) setTimeout(function(){
           console.log("ng-rpeat finished - Index: " + scope.$index);
        }, 1);
    };
});

app.controller('MyController', function($scope) {
    $scope.data = [1,2,3,4,5,6,7,8,9,10,12,12,13,14,15,16,17,18,19,20];

    $scope.buttonClicked = function() {
        console.log('Btn clicked');
        $scope.randomItems = getRandomItems(this.data.length);
    };
});

HTML

<div ng-app="myApp">
    <div ng-controller="MyController">
        <button ng-click="buttonClicked()">Highlight random</button>
        <ul class="item" >
            <li ng-repeat="item in data" ng-class="{highlight: randomItems.indexOf($index) > -1}" on-last-repeat>{{ item }} </li>
        </ul>
    </div>
</div>

Link to fiddle: https://jsfiddle.net/hbhodgm3/

So how the "app" works is that it lists the content of the data-array then when you click the "highlight"-button it randomly highlights 2 in the list. So my problem is that I want to have a callback function for when the highlighting/DOM-render is done. I found a way to do this for the initial ng-repeat with $scope.first and $scope.last to check when ng-repeat is done, but doesn't seem to work with the highlighting.

Hope I managed to explain the problem,

Thanks in advance.

3
  • What you're catching is the last rendering of the loop, not the new digest cycle update. Why don't you just do your thing after $scope.randomItems = getRandomItems(this.data.length); ? Commented Apr 11, 2016 at 11:54
  • If I handle to event after $scope.randomItems = getRandomItems(this.data.length); it appears to start before the change has been rendered. I want the be able to find a callback for when the change (highlight) has been rendered. Working on a little DOM-render experiment with Angular and the list in this case is 10 000+ and then the code begins executing before change has been rendered. Commented Apr 11, 2016 at 12:01
  • If the list is that long then it's probably best practice to chunk it into whatever size the view allows for give or take some for smoothing out scrolling through your list. You can't expect every client to be perfectly capable of handling a data-set that large and rendering it in its entirety. Commented Apr 11, 2016 at 12:10

1 Answer 1

0

See $q and Promises for a better understanding of how to work with the asynchronous nature of angular.

Presuming getRandomItems(this.data.length); is an API call that could take seconds to perform:

asyncItems(this.data.length).then(function(randoms){

  $scope.randomItems = randoms;
  //handle post rendering callback
});


function asyncItems(length) {
  var deferred = $q.defer();
  var items = getRandomItems(length);
  if (items){
    deferred.resolve(items);
  }   
  else {
    //no items :(
    deferred.reject([]);
  }

  return deferred.promise;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.