Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OrderBy and progressive-loading AngularJS

I'm having a problem when I use orderBy in a ng-repeat with an autoincrementing limitTo. When the page load a few elements the directive stops working and stops increasing the element limit.

This is the html:

<div class="row" id="main">
        <div class="col-xs-12 col-sm-6 col-md-3 col-lg-2 block animate"
             ng-if="!errorDialogActive"
             ng-repeat="build in builds.builds.build | limitTo:totalDisplayed | orderBy:'lastBuildDetails.startDate' : true track by build._id"
             ng-class="{'running': project.running ,'block-green': build._status ==='SUCCESS','block-red': build._status==='FAILURE'}"
             id="{{build._id}}"
             progressive-loading>
            <div class="title-container animate" ><p>{{build._buildTypeId}}</p></div>
            <div class="update-container animate col-xs-12">
            <time class="time">{{build.buildDate | date : 'dd.MM.yyyy H:mm:s'}} </time>
            </div>
        </div>
    </div>

This is the directive:

return function (scope) {
    if (scope.$last) {
        $timeout(function () {
            console.log('Im the last Displayed, Loading more');
            scope.loadMore();
        }, 100);
    }
};

And finally the loadMore function

    $scope.loadMore = function () {
        if ($scope.totalDisplayed >= $scope.size) {
            console.log('no more builds : ' + $scope.totalDisplayed);
            $scope.loaded=true;
        } else {
            $scope.totalDisplayed += 2;
            console.log('More : ' + $scope.totalDisplayed);
            $scope.totalDisplayedPercentage = (($scope.totalDisplayed*100)/$scope.size);
            console.log('Percentage : ' + $scope.totalDisplayedPercentage);
        }
    };

Sorry for my English, if you do not understand me or need more information, please let me know.

like image 244
Vistor Avatar asked Nov 01 '22 06:11

Vistor


1 Answers

Your directive link function is calling only for a new rendered element, so when orderBy is work, new rendered element can placed in middle and special property scope.$last of course will be false, so just not starting timeout.

For solving your can emulate counter, something like:
NOTE: this simplest sample, possibly working correct only when one on page

app.directive('progressiveLoading', ['$timeout', function ($timeout) { 
    var counter=1;
    return function (scope) { 
        if (counter == scope.displayStep) { 
            counter = 1;
            $timeout(function () { 
                console.log('Im the last Displayed, Loading more'); 
                scope.loadMore(); 
            }, 500); 
        }else{
            counter += 1;
        }
    }; 
}]);

Very simplified sample:

// Code goes here
var app = angular.module('app', []);

app.directive('progressiveLoading', ['$timeout',
  function($timeout) {
    var counter = 1;
    return function(scope) {
      if (counter == scope.displayStep) {
        counter = 1;
        $timeout(function() {
          console.log('Im the last Displayed, Loading more');
          scope.loadMore();
        }, 500);
      } else {
        counter += 1;
      }
    };
  }
]);

app.controller('ctrl', ['$scope',
  function($scope) {
    $scope.totalDisplayed = 2;
    $scope.displayStep = 2;
    $scope.loaded = false;

    $scope.build = [{
      _id: 1,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 1
      },
      _buildTypeId: 1
    }, {
      _id: 2,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 10
      },
      _buildTypeId: 2
    }, {
      _id: 3,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 9
      },
      _buildTypeId: 3
    }, {
      _id: 4,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 8
      },
      _buildTypeId: 4
    }, {
      _id: 5,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 7
      },
      _buildTypeId: 5
    }, {
      _id: 6,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 6
      },
      _buildTypeId: 6
    }, {
      _id: 7,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 5
      },
      _buildTypeId: 7
    }, {
      _id: 8,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 4
      },
      _buildTypeId: 8
    }, {
      _id: 9,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 3
      },
      _buildTypeId: 9
    }, {
      _id: 10,
      _status: 'SUCCESS',
      lastBuildDetails: {
        startDate: 2
      },
      _buildTypeId: 10
    }];
    $scope.size = $scope.build.length;
    $scope.totalDisplayedPercentage = (($scope.totalDisplayed * 100) / $scope.size);

    $scope.loadMore = function() {
      console.log('loadMore', $scope.totalDisplayed, $scope.size);
      if ($scope.totalDisplayed >= $scope.size) {
        console.log('no more builds : ' + $scope.totalDisplayed);
        $scope.loaded = true;
      } else {
        $scope.totalDisplayed += $scope.displayStep;
        console.log('More : ' + $scope.totalDisplayed);
        $scope.totalDisplayedPercentage = (($scope.totalDisplayed * 100) / $scope.size);
        console.log('Percentage : ' + $scope.totalDisplayedPercentage);
      }
    };
  }
])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div class="row" id="main" ng-app="app" ng-controller="ctrl">
<div>{{totalDisplayedPercentage}}%</div>  
  <div class="col-xs-12 col-sm-6 col-md-3 col-lg-2 block animate" ng-repeat="build in build | limitTo:totalDisplayed | orderBy:'lastBuildDetails.startDate' : true track by build._id" ng-class="{'running': project.running ,'block-green': build._status ==='SUCCESS','block-red': build._status==='FAILURE'}"
  id="{{build._id}}" progressive-loading="">
    <div class="title-container animate">
      <p>{{build._buildTypeId}}</p>
    </div>
  </div>
</div>
like image 198
Grundy Avatar answered Nov 15 '22 04:11

Grundy