угловая сетка сетки uiApi.infiniteScroll.on.needLoadMoreData не работает при изменении данных

Я использую угловую ui-сетку 3.2.5

Ниже приведены сетки

$scope.gridOptions = {
    infiniteScrollRowsFromEnd: 40,
    infiniteScrollUp: true,
    infiniteScrollDown: true,
    enableColumnMenus: false, // Remove hide columns options
    columnDefs: $scope.myDefs,
    data: 'data',
    onRegisterApi: function (gridApi) {
        gridApi.infiniteScroll.on.needLoadMoreData($scope, $scope.getDataDown);
        gridApi.infiniteScroll.on.needLoadMoreDataTop($scope, $scope.getDataUp);
        $scope.gridApi = gridApi;
    }
};

function updateGrid(filteredData) {
    $scope.response = filteredData;

    $scope.firstPage = 1;
    $scope.lastPage = 1;
    $scope.totalPages = Math.ceil($scope.response.length / $scope.pageSize);

    $scope.gridApi.infiniteScroll.setScrollDirections(false, false);
    $scope.data = [];
    $scope.data = $scope.response.slice(0, $scope.pageSize);

    $timeout(function () {
        $scope.gridApi.infiniteScroll.resetScroll($scope.firstPage > 0, $scope.lastPage < $scope.totalPages);
    });
};

когда мы выполняем прокрутку gridApi.infiniteScroll.on.needLoadMoreData($scope, $scope.getDataDown); работаем хорошо, но мы подталкиваем новые данные при изменении данных в сетке $scope.$watch( 'data', updateGrid); то по окончании прокрутки gridApi.infiniteScroll.on.needLoadMoreData не вызывает метод getDataDown и прокрутки, хотя есть больше данных.

Что может быть проблемой?

Ответы

Ответ 1

var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.infiniteScroll']);

app.controller('MainCtrl', function ($scope, $http, $timeout) {
  var vm = this;

  vm.gridOptions = {
    infiniteScrollRowsFromEnd: 40,
    infiniteScrollUp: true,
    infiniteScrollDown: true,
    columnDefs: [
      { name:'id'},
      { name:'name' },
      { name:'age' }
    ],
    data: 'data',
    onRegisterApi: function(gridApi){
      gridApi.infiniteScroll.on.needLoadMoreData($scope, getDataDown);
      gridApi.infiniteScroll.on.needLoadMoreDataTop($scope, getDataUp);
      vm.gridApi = gridApi;
    }
  };

  $scope.data = [];

  vm.firstPage = 2;
  vm.lastPage = 2;

  function getFirstData() {
    return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
    .then(function(response) {
      var newData = getPage(response.data, vm.lastPage);

      $scope.data = $scope.data.concat(newData);
    });
  }

  function getDataDown() {
    return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
    .then(function(response) {
      vm.lastPage++;
      var newData = getPage(response.data, vm.lastPage);
      vm.gridApi.infiniteScroll.saveScrollPercentage();
      $scope.data = $scope.data.concat(newData);
      return vm.gridApi.infiniteScroll.dataLoaded(vm.firstPage > 0, vm.lastPage < 4).then(function() {checkDataLength('up');});
    })
    .catch(function(error) {
      return vm.gridApi.infiniteScroll.dataLoaded();
    });
  }

  function getDataUp() {
    return $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pageshttps://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/10000_complex.json')
    .then(function(response) {
      vm.firstPage--;
      var newData = getPage(response.data, vm.firstPage);
      vm.gridApi.infiniteScroll.saveScrollPercentage();
      $scope.data = newData.concat($scope.data);
      return vm.gridApi.infiniteScroll.dataLoaded(vm.firstPage > 0, vm.lastPage < 4).then(function() {checkDataLength('down');});
    })
    .catch(function(error) {
      return vm.gridApi.infiniteScroll.dataLoaded();
    });
  }

  function getPage(data, page) {
    var res = [];
    for (var i = (page * 100); i < (page + 1) * 100 && i < data.length; ++i) {
      res.push(data[i]);
    }
    return res;
  }

  function checkDataLength( discardDirection) {
    // work out whether we need to discard a page, if so discard from the direction passed in
    if( vm.lastPage - vm.firstPage > 3 ){
      // we want to remove a page
      vm.gridApi.infiniteScroll.saveScrollPercentage();

      if( discardDirection === 'up' ){
        $scope.data = $scope.data.slice(100);
        vm.firstPage++;
        $timeout(function() {
          // wait for grid to ingest data changes
          vm.gridApi.infiniteScroll.dataRemovedTop(vm.firstPage > 0, vm.lastPage < 4);
        });
      } else {
        $scope.data = $scope.data.slice(0, 400);
        vm.lastPage--;
        $timeout(function() {
          // wait for grid to ingest data changes
          vm.gridApi.infiniteScroll.dataRemovedBottom(vm.firstPage > 0, vm.lastPage < 4);
        });
      }
    }
  }

  vm.reset = function() {
    vm.firstPage = 2;
    vm.lastPage = 2;

    // turn off the infinite scroll handling up and down - hopefully this won't be needed after @swalters scrolling changes
    vm.gridApi.infiniteScroll.setScrollDirections( false, false );
    $scope.data = [];

    getFirstData().then(function(){
      $timeout(function() {
        // timeout needed to allow digest cycle to complete,and grid to finish ingesting the data
        vm.gridApi.infiniteScroll.resetScroll( vm.firstPage > 0, vm.lastPage < 4 );
      });
    });
  };

  getFirstData().then(function(){
    $timeout(function() {
      // timeout needed to allow digest cycle to complete,and grid to finish ingesting the data
      // you need to call resetData once you've loaded your data if you want to enable scroll up,
      // it adjusts the scroll position down one pixel so that we can generate scroll up events
      vm.gridApi.infiniteScroll.resetScroll( vm.firstPage > 0, vm.lastPage < 4 );
    });
  });
});
.grid {
  width: 500px;
  height: 400px;
}
<!doctype html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular-touch.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular-aria.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.7.1/ui-grid.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/angular-ui/bower-ui-grid/ui-grid.min.css" type="text/css">

  </head>
  <body ng-app="app"> 
<div ng-controller="MainCtrl as $ctrl">
  <button id="reset" class="button" ng-click="$ctrl.reset()">Reset</button>
  <span> &nbsp; &nbsp; First page: {{ $ctrl.firstPage }} &nbsp; &nbsp; Last page: {{ $ctrl.lastPage }}  &nbsp; &nbsp; data.length: {{ data.length }} </span>
  <div ui-grid="$ctrl.gridOptions" class="grid" ui-grid-infinite-scroll></div>
</div>
  </body>
</html>

Ответ 2

У меня была та же проблема, которую я решил, как показано ниже. Это происходит потому, что я предполагаю, что вы не реализовали свою функцию needLoadMoreDataTop. Просто добавьте приведенный ниже код, и все будет хорошо. Также установите infiniteScrollUp как true для параметров сетки.

_.invoke(gridApi, 'infiniteScroll.on.needLoadMoreDataTop', $scope , topFunction);

function topFunction() {
  gridApi.infiniteScroll.dataLoaded(true,true);
}