How to call function after all multiple nested ng-repeats have finished?

Viewed 53

I have been reading many threads on using a directive or $last to call a function at the end of an ng-repeat, even two level nested ng-repeats, but nothing regarding the level of nested ng-repeats I have. I think the issue is related to autoloading a new page/view while the ng-repeat is still rendering elements...the new page loads but going back to the list the ng-repeat created causes weird things to happen.

Simple example:

<div ng-repeat="products in categories" ng-init="$last && listLoaded()"> // length = 12
  <div ng-repeat="product in products">
    <div ng-if="product.type == 1" ng-repeat="feature in product.features"> // length = 20
      <div ng-if="feature.specs == 1" ng-repeat="specs in feature.specs"> // length = 40
      </div>
      <div ng-if="feature.desc == 1" ng-repeat="desc in feature.desc"> // length = 4
      </div>
      <div ng-if="feature.reviews > 0" ng-repeat="review in feature.reviews"> // length = 125
        <div>{{review.review}}
        <div ng-if="review.pictures > 0" ng-repeat="pictures in review.pictures">  // length = 3
           <img src="blah.com/imgs/{{picture.picURL}}" id="picture.pictureID" ng-click="enlargeImage(picture.pictureID)">
        </div>
      </div>
    </div>
  </div>
</div>


$scope.listLoaded = function() {
  if ($stateParams.prodID) {
     //external ID passed in, autoload featurePage
     $state.go("tabs/search/" + featurePage", {product : productID}) ;
  }
}

$scope.enlargeImage = function(id) {
  var el = document.getElementById(id) ;
  el.style.border = "1px solid red" ;
  el.style.display = "block" ;
  console.log(el) ;
  angular.element('#'+id).border = "1px solid red" ;
  angular.element('#'+id.display = "block" ;
}

As you can see, there are multiple nested ng-repeats, all of varying lengths that will all have vastly different rendering times. I need to execute a function when ALL items, from all nested ng-repeats are done rendering, the function listLoaded calls to another tab/view/page.

When an external ID is passed in it autoloads a feature page. It all works, featurePage is loaded with all the correct info. However, when I go back to the list page, the full page is there, but when clicking on the images, though the function is executing, the images aren't getting the styles applied to them.

The console.log output of el shows the styles applied to the element, but in Developer Tools, in the Elements -> Styles section, the styles aren't actually being applied to the element and visually none of the image styles are changing.

     console.log output:
     <img src="blah.com/imgs/{{picture.picURL}}" id="picture.pictureID" ng-click="enlargeImage(picture.pictureID)" style="border:1px solid red;display:block;">

After an autoload to the featurePage, if I refesh the product list page, the same elements that weren't rendering style changes still have issues, they won't change. The view is cached. When I remove page caching - everything works properly. So, the issue must be related to the DOM elements not fully rendering or being added to the DOM.

When I comment out the listLoaded() function and don't force an autoload of the featurePage, the full list renders and all the ng-clicks work properly. I can then manually click on a specific product to go to the featurePage - and then back to the list again and everything still works. I think the issue has something to do with the angular.element not fully loading before the page view is auto-loaded to the featurePage - but I am not certain. All I know is everything works when I don't auto-redirect to the featurePage

I even tried a directive on the first ng-repeat and still have the same issues:

.directive('listRepeatDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('color','blue');
    if (scope.$last){
      scope.listLoaded() ;
    }
  };
})
0 Answers
Related