OrderBy и прогрессивная загрузка AngularJS

У меня проблема, когда я использую orderBy в ng-repeat с автоинкрементным limitTo. Когда страница загружает несколько элементов, директива перестает работать и перестает увеличивать лимит элементов.

Это 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);
    }
};

И, наконец, функция loadMore

    $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);
        }
    };

Извините за мой английский, если вы меня не понимаете или вам нужна дополнительная информация, пожалуйста, дайте мне знать.


person Vistor    schedule 16.04.2015    source источник
comment
можете предоставить jsfiddle или планкер?   -  person Grundy    schedule 16.04.2015
comment
Я пытался, но у меня не получается заставить плункер работать, слишком много внешних зависимостей, я могу показать, как это работает, и добавить код, если это необходимо :(   -  person Vistor    schedule 16.04.2015
comment
попробуйте использовать только код из OP с примерами данных для plunker   -  person Grundy    schedule 16.04.2015
comment
Вот демонстрационное видео моей проблемы recordit.co/jAqQundmJC Еще раз извините, что не смог предоставить плункер   -  person Vistor    schedule 16.04.2015
comment
попробуй посмотреть ошибки в консоли   -  person Grundy    schedule 16.04.2015
comment
Консоль не показывает ошибок, я начинаю думать, что проблема в orderBy и scope.$last, возможно, $scope.last не то же самое, когда я использую orderBy, и это приводит к тому, что программа перестает работать   -  person Vistor    schedule 16.04.2015
comment
Давайте продолжим обсуждение в чате.   -  person Grundy    schedule 16.04.2015


Ответы (1)


Ваша директивная функция ссылки вызывает только новый отображаемый элемент, поэтому, когда orderBy работает, новый отображаемый элемент может быть помещен в середину, а специальное свойство scope.$last, конечно, будет ложным, поэтому просто не запускайте timeout.

Для решения вопроса о том, что вы можете эмулировать счетчик, что-то вроде:
ПРИМЕЧАНИЕ: этот простейший пример, возможно, работает правильно только тогда, когда он находится на странице

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;
        }
    }; 
}]);

Очень упрощенный образец:

// 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>

person Grundy    schedule 16.04.2015
comment
Работает отлично, спасибо, и извините, что так долго не отвечал. - person Vistor; 17.04.2015
comment
@Vistor это не готовое решение, просто образец, вы должны его хорошо протестировать. Как я уже сказал выше - возможно, в некоторых случаях он не работает или работает с ошибками. - person Grundy; 17.04.2015
comment
Я знаю, но я тестирую его в своем приложении, и проблем нет, он работает нормально во всех случаях. - person Vistor; 17.04.2015
comment
@Vistor, так что рад помочь тебе :-) - person Grundy; 17.04.2015
comment
Вы научились использовать плункер? решение gr8, но не могу его реализовать. Учтите, что я получаю данные сборки из базы данных. - person KumarHarsh; 21.09.2017
comment
@KumarHarsh, я не совсем понимаю, что ты имеешь в виду. Можешь немного объяснить? - person Grundy; 21.09.2017
comment
На самом деле я не смог реализовать ваш код, но теперь тот же код работает нормально после включения Order by.... Может ли он работать без Order By? Потому что мне не нужно упорядочивать. - person KumarHarsh; 21.09.2017
comment
@KumarHarsh, возможно, лучше, если вы зададите свой вопрос с образцом своего кода. Насколько я понимаю, ваша проблема не должна зависеть от фильтра orderBy - person Grundy; 21.09.2017