AngularJS中服务器端和客户端分页的组合

时间:2015-11-29 09:59:35

标签: javascript angularjs spring-mvc pagination

我正在为后端和AngularJS使用spring框架。我需要对一个表使用服务器端和客户端分页,因此我将页码和页面大小传递给休息服务。现在我需要做以下情况:

如果我在数据库中有20000条记录:

  1. 从数据库中获取前2500条记录,然后通过它们进行分页。

  2. 在对前2500条记录进行分页后,获取下一条2500条记录(从2501条到5000条),依此类推,直至完成数据库中的所有记录。

  3. 我可以使用Angular数据表或任何Angular表吗?

1 个答案:

答案 0 :(得分:0)

我们对您描述的要求完全相同。我们在网上搜索过我们没有得到解决方案。最后我们研究并提出了一个解决方案。希望它能帮助正在寻找解决方案的其他人。

我们正在使用Angular ui grid。在angular ui.grid中,您可以使用默认的客户端分页,也可以实现外部(或服务器端)分页。

但是,在您的要求中,您需要组合客户端和服务器端分页,这是非常灵活的,当您拥有大量数据(Lacks中的记录数量)时非常需要。

如果您不知道如何使用服务器端分页,请查看How to use Angular UI-Grid with Server Side Paging问题。您可以查看服务器端分页实施http://plnkr.co/edit/UttxPkXG8fYQDX85fnyZ?p=preview

我正在修改此实现,以实现客户端和服务器端分页的组合。

var useHybridPagination = true;
var paginationPageSize = 25;
var serverPaginationPageSize = 2500;    
var serverPaginationOffset = 0;
var serverPaginationGridData = {};

var clientPaginationOptions  = {
        pageNumber: 1,
        pageSize: paginationPageSize,           
      };

var serverPaginationOptions = {
        pageNumber: 1,
        pageSize: serverPaginationPageSize,         
      };    

var paginationRowRange = {}
paginationRowRange.startRowIndex = 1;
paginationRowRange.endRowIndex = paginationPageSize;

var serverPaginationRowRange = {}
serverPaginationRowRange.startRowIndex = 1;
serverPaginationRowRange.endRowIndex = serverPaginationPageSize;   

我将使用服务器端分页逻辑来提取每2,500条记录。并且要在客户端(2500条记录)的页面之间导航,将进行一些修改。如果用户搜索的新页面存在于客户端的2500条记录中,则按 serverPaginationOptions.pageSize 所示切片记录数并加载网格。或者取下2500条记录&重新评估行索引。

$scope.clientPaginationOptions  = clientPaginationOptions ;
$scope.serverPaginationOptions = serverPaginationOptions;
$scope.paginationRowRange = paginationRowRange;
$scope.serverPaginationRowRange = serverPaginationRowRange;
$scope.serverPaginationOffset = serverPaginationOffset;
$scope.serverPaginationGridData = serverPaginationGridData;

$scope.gridOptions = {
    paginationPageSizes: [25, 50, 75],
    paginationPageSize: $scope.clientPaginationOptions .pageSize,
    useExternalPagination: true,        
    columnDefs: [
      { name: 'name' },
      { name: 'gender', enableSorting: false },
      { name: 'company', enableSorting: false }
    ],
    onRegisterApi: function(gridApi) {
      $scope.gridApi = gridApi;

      gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
        $scope.clientPaginationOptions .pageNumber = newPage;
        $scope.clientPaginationOptions .pageSize = pageSize;

        let startRowIndex = (($scope.clientPaginationOptions .pageNumber - 1) * $scope.clientPaginationOptions .pageSize) + 1;
        let endRowIndex =  (startRowIndex - 1 ) + clientPaginationOptions .pageSize;            

        if(endRowIndex > $scope.serverPaginationRowRange.endRowIndex || startRowIndex < $scope.serverPaginationRowRange.startRowIndex){             

            $scope.serverPaginationOptions.pageNumber = parseInt(($scope.clientPaginationOptions .pageNumber * pageSize)/$scope.serverPaginationOptions.pageSize) + 1;

            let serverStartRowIndex = (($scope.serverPaginationOptions.pageNumber - 1) * $scope.serverPaginationOptions.pageSize) + 1;
            let serverEndRowIndex =  (serverStartRowIndex - 1 ) + $scope.serverPaginationOptions.pageSize;                  

            let paginationRowRangeTmp = {}
            paginationRowRangeTmp.startRowIndex = serverStartRowIndex;
            paginationRowRangeTmp.endRowIndex = serverEndRowIndex;    
            $scope.serverPaginationRowRange = paginationRowRangeTmp;                

            $scope.serverPaginationOffset = serverStartRowIndex - 1;
        }

        startRowIndex = startRowIndex - $scope.serverPaginationOffset;
        endRowIndex = endRowIndex - $scope.serverPaginationOffset;          

        let paginationRowRangeTmp = {}
        paginationRowRangeTmp.startRowIndex = startRowIndex;
        paginationRowRangeTmp.endRowIndex = endRowIndex;    
        $scope.paginationRowRange = paginationRowRangeTmp; 

        getPage();
      });
    }
};
getPage();

var getPage = function() {

    if(useHybridPagination && !_.isEmpty($scope.serverPaginationGridData)){
        var currentPageData = getcurrentPageData();
        $timeout(function() {
            $scope.gridOptions.data = datatoLoadGrid;
           }, 1);
    }
    else{
        var url = 'https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json';
        $http.get(url,$scope.serverPaginationRowRange)
            .then(function (returnData) {
                $scope.gridOptions.totalItems = returnData.data.totalPaginationRecords;
                let datatoLoadGrid = returnData.data.gridData;

                if(useHybridPagination){
                    $scope.serverPaginationGridData = datatoLoadGrid;
                    datatoLoadGrid = getcurrentPageData();
                }
                $scope.gridOptions.data = datatoLoadGrid;
            });
    }
};  

var getcurrentPageData = function(){
    var gridData = [];

    var tmpGridrecords = $scope.serverPaginationGridData;
    if(!_.isEmpty(tmpGridrecords) && tmpGridrecords.length > 0)
        gridData = tmpGridrecords.slice($scope.paginationRowRange.startRowIndex-1, $scope.gridOptions.endRowIndex);

    return gridData;
};  

如您所见,Web服务(或API)返回具有2个属性的数据对象 - totalPaginationRecords&amp;的GridData。 totalPaginationRecords 是可能的记录总数,即在我们的情况下是20,000。 gridData 是要加载的网格数据(页面大小为2500)。

处理所有角落条件。希望能帮助到你。欢迎提出改进此解决方案的所有建议/更正。