1

I made AngularJS pagination with spring mvc It works well ,but the application get a large amount of data from database so the application is very slow when I get first page because it get all records,Can anyone help me to solve this problem?I want to get subset of data from database depending on angularJS pagination

Spring mvc Controlller

@RequestMapping(value = "/rest/contacts",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public List<Contact> getAll() {
    return contactRepository.findAll();
} 

AngularJS Service

pagingpocApp.factory('Contact', function ($resource) {
    return $resource('app/rest/contacts/:id', {}, {
        'query': { method: 'GET', isArray: true},
        'get': { method: 'GET'}
    });


});

AngularJS Controller

  pagingpocApp.controller('ContactController', function ($scope,  $filter,resolvedContact, Contact, resolvedRole) {

    $scope.contacts = resolvedContact;

        var sortingOrder = 'firstName';
        $scope.sortingOrder = sortingOrder;
        $scope.reverse = false;
        $scope.filteredItems = [];
        $scope.groupedItems = [];
        $scope.itemsPerPage = 10;
        $scope.pagedItems = [];
        $scope.currentPage = 0;

        var searchMatch = function (haystack, needle) {
            if (!needle) {
                return true;
            }
            return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
        };

        // init the filtered items
        $scope.search = function () {
            $scope.filteredItems = $filter('filter')($scope.contacts, function (item) {
                for(var attr in item) {
                    if (searchMatch(item[attr], $scope.query))
                        return true;
                }
                return false;
            });
            // take care of the sorting order
            if ($scope.sortingOrder !== '') {
                $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
            }
            $scope.currentPage = 0;
            // now group by pages
            $scope.groupToPages();
        };

        // calculate page in place
        $scope.groupToPages = function () {
            $scope.pagedItems = [];

            for (var i = 0; i < $scope.filteredItems.length; i++) {
                if (i % $scope.itemsPerPage === 0) {
                    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
                } else {
                    $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
                }
            }
        };

        $scope.range = function (start, end) {
            var ret = [];
            if (!end) {
                end = start;
                start = 0;
            }
            for (var i = start; i < end; i++) {
                ret.push(i);
            }
            return ret;
        };

        $scope.prevPage = function () {
            if ($scope.currentPage > 0) {
                $scope.currentPage--;
            }
        };

        $scope.nextPage = function () {
            if ($scope.currentPage < $scope.pagedItems.length - 1) {
                $scope.currentPage++;
            }
        };

        $scope.setPage = function () {
            $scope.currentPage = this.n;
        };

        // functions have been describe process the data for display
        $scope.search();

        // change sorting order
        $scope.sort_by = function(newSortingOrder) {
            if ($scope.sortingOrder == newSortingOrder)
                $scope.reverse = !$scope.reverse;

            $scope.sortingOrder = newSortingOrder;

            // icon setup
            $('th i').each(function(){
                // icon reset
                $(this).removeClass().addClass('icon-sort');
            });
            if ($scope.reverse)
                $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-up');
            else
                $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-down');
        };

});

1 Answer 1

0

One quick option would be to create a get method on your API that only returns a subset of the data, maybe only 25 contacts at a time, or a page or two worth of data. Then you could create a service in angular that makes that get call every 3 seconds or so to get the next 25 contacts. A sort of lazy loading technique.

Ben Nadel does a great job in this article of outlining how his company handles large sets of images being loaded to a page using a lazy loading technique. Reading through his example could give you a nice starting point.

Edit: I'm also going to recommend you refer to this solution for an answer slightly more on point to what you're looking to achieve. He recommends pushing data to your controller as soon as it's found:

 function MyCtrl($scope, $timeout, $q) {
        var fetchOne = function() {
            var deferred = $q.defer();
            $timeout(function() {
                deferred.resolve([random(), random() + 100, random() + 200]);
            }, random() * 5000);
            return deferred.promise;
        };

        $scope.scans = [];
        for (var i = 0; i < 2; i++) {
            fetchOne().then(function(items) {
                angular.forEach(items, function(item) {
                    $scope.scans.push(item);
                });
            });
        };
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.