【问题标题】:Angular UI Grid 'gridApi.infiniteScroll.on.needLoadMoreData' doesn't work with changes in dataAngular UI Grid 'gridApi.infiniteScroll.on.needLoadMoreData' 不适用于数据更改
【发布时间】:2017-04-08 12:20:21
【问题描述】:

我正在使用angular-ui-grid 3.2.5

使用gridApi.infiniteScroll.on.needLoadMoreData($scope, $scope.getDataDown) 滚动效果很好,但是当我们通过$scope.$watch('data', updateGrid) 在网格中更改数据时推送新数据时,滚动结束时gridApi.infiniteScroll.on.needLoadMoreData 不会调用getDataDown 方法并且滚动停止虽然还有更多数据。

这里是gridOptions

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

这是updateGrid() 的实现

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

可能是什么问题?

【问题讨论】:

  • 请显示$scope.getDataDown$scope.getDataUp的功能

标签: javascript angularjs angular-ui-grid ui-grid


【解决方案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>

如果您可以将 ui.grid 更新到最新版本。我为您找到了这个示例,但如果您不提供这些函数 getDataDown 和 getDataUp,我将无法解决您的问题。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,我解决了它,如下所示。 发生这种情况是因为我假设您尚未实现 needLoadMoreDataTop 函数。只需添加以下代码,您应该会很好。还要在网格选项上将 infiniteScrollUp 设置为 true。

    _.invoke(gridApi, 'infiniteScroll.on.needLoadMoreDataTop', $scope , topFunction);
    
    function topFunction() {
      gridApi.infiniteScroll.dataLoaded(true,true);
    }
    

    【讨论】:

      【解决方案3】:

      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 = 5;
        vm.lastPage = 5;
      
        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 < 5).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 < 5).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 < 5);
              });
            } 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 = 5;
          vm.lastPage = 5;
      
          // 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 < 5 );
            });
          });
        };
      
        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 < 5 );
          });
        });
      });
      .grid {
        width: 400px;
        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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-19
        • 2018-06-12
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 2019-07-25
        • 1970-01-01
        相关资源
        最近更新 更多