5

How possible to make custom directive in AngularJS waiting until ng-repeat will render?

What the problem I've stucked on: the directive init before li elements are rendered, so DOM is not ready and the height of the block computed not right.

This is my code

AngularJS

.directive('navCollapse', function(){
 return {
  restrict: 'A', 
  scope: {
     navItems: '=',
     navScrollOn: '='
  },
  link: function($scope, $element, $attrs) {
           var $navList = $element.find('ul'),
               navItemsChildren = $navList.children('li'),
               navItemsChildrenDefault = navItemsChildren.get(),
               navItemsChildrenGet = navItemsChildren.get(),
               showItems = ($scope.navItems !== undefined) ? $scope.navItems : 6,
               showItemsOnScroll = ($scope.navItems !== undefined) ? $scope.navScrollOn : navItemsChildren.length,
               isCollapsed  = false,
               calculateHeight = navItemsChildren.outerHeight() * showItems,
               calculateFullHeight = navItemsChildren.outerHeight() * showItemsOnScroll;
           $navList.wrap('<div class="links-wrap" style="max-height:'+ calculateHeight +'px"></div>');

           function sortNav(element) {
              element.sort(function(a,b){
                var keyA = $(a).find('a').text();
                var keyB = $(b).find('a').text();

                if (keyA < keyB) return -1;
                if (keyA > keyB) return 1;
                return 0;
              });
           }

           $element.find('.show-more').on('click', function(e) {
              var linksWrap = $('.links-wrap');

              if (isCollapsed === false) {
                 isCollapsed = true;

                 sortNav(navItemsChildrenGet);
                 $navList.empty();
                 $.each(navItemsChildrenGet, function(i, li){
                    $navList.append(li);
                 });

                 linksWrap.css({
                    'max-height' : calculateFullHeight + 'px',
                    'overflow' : 'auto'
                 });

              } else {
                 isCollapsed = false;

                 $navList.empty();
                 $.each(navItemsChildrenDefault, function(i, li){
                    $navList.append(li);
                 });

                 linksWrap.css('max-height', calculateHeight+'px');
                 linksWrap.css('overflow', 'hidden');
              }
           });
  }}})

HTML

<div class="links links-btn-more">
  <div ng-controller="categoriesCtrl" nav-collapse nav-scroll-on="10" nav-items="4">
  <h4>Categories</h4>
  <hr>

  <ul>
     <li ng-repeat="cat in categories.aList">
        <a ui-sref="collections({categoryId:cat.id})" title="">{{cat.name}} </a>
     </li>
  </ul>

  <button class="btn show-more"></button>

  • 1
    is `navCollapse ` and `ngRepeat` in the same element? If yes, you can try assigning a higher `priority` for `navCollapse` – Samir Das Jun 08 '15 at 08:23
  • 1
    @Samir Update the code with HTML – Constantine Golub Jun 08 '15 at 08:31
  • 4
    this is a classic issue: you can dispatch an event when ng-repeat are finished and then time your directive on it. look at this page:http://stackoverflow.com/questions/15207788/calling-a-function-when-ng-repeat-has-finished – Eagle1 Jun 08 '15 at 08:45
  • 1
    @Eagle1 Thanks, it works. – Constantine Golub Jun 08 '15 at 21:06
  • 1
    @Eagle1, you should post your comment as an answer, and Constantine, you should mark it as the accepted answer. This will help future visitors to this page who are trying to answer the same question. (Also, it will boost your reputation on stackoverflow!) – MattSidor Sep 18 '15 at 22:44

0 Answers0