AngularJS Scroll to pagination向服务器发送多个帖子请求

时间:2016-11-17 06:32:05

标签: javascript angularjs pagination

我正在开发MEAN应用程序。我实现了延迟加载滚动到分页。页面滚动和到达结束时发送2次请求到服务器。我不知道是什么原因?为什么会这样?

以下是我的代码。请查看并指导我。希望下面的代码可以帮助您解决。

请求的firebug快照

enter image description here

控制器:

(function () {

    'use strict';
    /**
     * Photo Controller for photo features
     * @param {type} $rootScope
     * @param {type} $scope
     * @param {type} $state
     * @param {type} $timeout
     * @param {type} HzServices
     * @param {type} HzPhotoService
     * @param {type} Upload     * @returns {undefined}
     */
    function PhotoCtrl($rootScope, $scope, $state, $window, $routeParams, $timeout, HzServices, HzPhotoService, Upload, HzSocket, notifications) {
    /*
     * Initiliaze custom scrollbar for following features
     * rightside - my album list
     * add/edit album - emoji list
     */
    //Data loads when $viewContentLoaded.
    $scope.$on('$viewContentLoaded', function () {
        $scope.counter = 0;
        $scope.currentTab = 'all-photos';
        $scope.init();
        $scope.doAlbumList('', '', '', '', 0, 0);
    });

    // Scroll to top, when page loads
    angular.element("html, body").animate({
        scrollTop: 0
    }, 0);
    /*
     *Initialize select2 options for email ids
     */
    $scope.init = function () {
        $scope.select2Options = {
            multiple: true,
            'simple_tags': true,
            tokenSeparators: [','],
            tags: [], // Can be empty list.
            selectOnBlur: true,
            formatNoMatches: function () {
                return '';
            },
            dropdownCss: {display: 'none'}
        };
        $scope.myAlbumListConfig = HzServices.initNgScrollbarsConfig();
        $scope.myAlbumEmojiConfig = HzServices.initNgScrollbarsConfig();
        $scope.frmPhoto = null;
        $rootScope.photoIndex = 0;
        // Prevent to sent request to server by continuously click on "All photos"
        $scope.defaultAlbum = null;
        $scope.fullWidthClass = null;
        $scope.albums = {};
        $scope.albumsCount = null;
        $scope.myAlbums = {};
        $scope.myAlbumsCount = null;
        $scope.photos = {};
        $scope.photosByDate = {};
        $scope.photosCount = null;
        //set model variable for photo pagination
        $scope.photoRecordsOffset = 0;
        $scope.photoRecordsTotal = 0;
        $scope.photoYears = [];
        $scope.albumModel = {album_name: "", album_description: "", album_emoji: "", is_auto_generate: 0};
        $scope.myAlbumIsAutoGenerated = 1;
        $scope.photoModel = {};
        $scope.browsePhotoModel = {};
        // Set default global variables of edit album
        $scope.deletedPhotoTotal = 0;
        $scope.deleteFlag = false;
        $rootScope.emojis = {};
        $scope.arrPhoto = [];
        $scope.modelChkBrowsePhoto = {};
        $scope.selectedBrowsePhotoIden = [];
        $scope.selectedBrowsePhotoIndex = [];
        $scope.deSelectedBrowsePhotoIden = [];
        $scope.obsoleteBrowsePhotoIden = [];
        $scope.checkAllFlag = false;
        $scope.overBox = {};
        $scope.deleteBox = {};
        $scope.moveBox = {};
        $scope.overBoxFlag = false;
        $scope.deleteBoxFlag = false;
        $scope.moveBoxFlag = false;
        $scope.currentSelectedPhotoCount = 0;
        $scope.currentMovedPhotoCount = 0;
        $scope.currentDeletedPhotoCount = 0;
        $scope.filesLen = 0;
        $scope.counter = 0;
        $scope.flag = false;
        $scope.allowViewMore = null;
        $scope.searchTag = null;
    };

    /**
     * Lists available albums of user
     * @param {String} pagination
     * @param {String} album
     * @param {Number} recordsPerPage
     * @param {String} selectedTab
     * @param {Boolean} includeMovedPhotos
     * @returns {undefined}
     */
    $scope.doAlbumList = function (pagination, album, recordsPerPage, selectedTab, includeMovedPhotos, includeDeletedPhotos) {
        var includeMovedPhotos = (!!includeMovedPhotos) ? includeMovedPhotos : 0;
        var includeDeletedPhotos = (!!includeDeletedPhotos) ? includeDeletedPhotos : 0;
        HzServices.showActiveElementTab();
        angular.element("ul.error-log li").remove();
        //$rootScope.arrData = [];

        /*
         * Pagination params
         */
        var arrPhotoLen = $scope.arrPhoto.length;
        var photosLen = $scope.photos.length;
        $scope.allowViewMore = photosLen < $scope.photoRecordsTotal;
        if (!!pagination && pagination === "VIEWMORE") {
            $scope.photoRecordsOffset = $scope.photoRecordsOffset + $rootScope.recordsPerPage;
        }

        /*
         * Following condition is affected specficially when move photo to album and it requires
         * to display and update photos for those particular photos. There is not requires to update
         * other photos of an album
         * When $scope.arrPhoto is blank so it consider, default behaviour of listing, otherwise it lists only
         * those photos which are listed in edit photos option.
         */
        var data = {};
        if (arrPhotoLen === 0) {
            data = {
                q: $state.params.pid, // Userid
                album: album, // album Id
                // custom records offset used in move album section and update pagination used both recordsPerPage and recordsOffset
                // records per page
                recordsPerPage: (!!recordsPerPage) ? recordsPerPage : $rootScope.recordsPerPage,
                recordsOffset: $scope.photoRecordsOffset,
                // It includes photos which are moved from source album to destination album but source album reference is also present,
                // It helps to know which photo is moved from current album to destination album in move album tab.
                includeMovedPhotos: includeMovedPhotos,
                includeDeletedPhotos: includeDeletedPhotos,
                tag: $scope.searchTag
            };
        } else {
            data = {
                pid: $scope.arrPhoto
            };
        }
        console.log("data passed to server >>> >>>");
        console.log(data);
        /*
         * Pagination
         */
        console.time("album");
        var deferred = HzServices.deferred("/api/album/list", 'POST', data);
        deferred.then(
                function (res) {
                    $scope.flag = true;
                    /*
                     * success in repsonse
                     * Share common photo & album data across all controllers, directives by angular custom service.
                     */
                    var data = {album: {count: res.data.count.album, data: res.data.album}, albumWithDeletedPhoto: {count: res.data.count.albumWithDeletedPhoto, data: res.data.albumWithDeletedPhoto}, myAlbum: {count: res.data.count.myAlbum, data: res.data.myAlbum}, myAlbumWithDeletedPhoto: {count: res.data.count.myAlbumWithDeletedPhoto, data: res.data.myAlbumWithDeletedPhoto}, photo: {count: res.data.count.photo, data: res.data.photo}};
                    HzPhotoService.setSharedData(data);
                    if (false === !!$scope.myAlbum && false === !!$scope.myAlbumId) {
                        $scope.myAlbum = "All photos";
                        $scope.myAlbumId = "";
                        $scope.myAlbumIsAutoGenerated = 1;
                    }
                    //Create an array of magnific inline popup content
                    var sharedData = HzPhotoService.getSharedData();
                    //Get all albums list
                    $scope.albums = sharedData.album.data;
                    $scope.albumsCount = sharedData.album.count;
                    //Get all albums with deleted records list
                    $scope.albumsWithDeletedPhoto = sharedData.albumWithDeletedPhoto.data;
                    $scope.albumsWithDeletedPhotoCount = sharedData.albumWithDeletedPhoto.count;
                    //Get my custom albums list
                    $scope.myAlbums = sharedData.myAlbum.data;
                    $scope.myAlbumsCount = sharedData.myAlbum.count;
                    //Get my custom album with deleted records list
                    $scope.myAlbumWithDeletedPhoto = sharedData.myAlbumWithDeletedPhoto.data;
                    $scope.myAlbumWithDeletedPhotoCount = sharedData.myAlbumWithDeletedPhoto.count;
                    // Pagination if required
                    if (pagination === "VIEWMORE") {
                        $scope.photos = $scope.photos.concat(sharedData.photo.data);
                    } else {
                        if ($rootScope.recordsOffset === 0) {
                            $scope.photos = sharedData.photo.data;
                        }
                    }
                    $scope.photosByDate = HzPhotoService.setSharedDataByDate((pagination === "VIEWMORE") ? true : false);
                    //BrowsePhotoModel to pass all photos lists to directive
                    $scope.browsePhotoModel = $scope.photos;
                    //$scope.uploadResults = $scope.photos;
                    $scope.photosCount = sharedData.photo.count;
                    if (includeMovedPhotos === 0 || includeDeletedPhotos === 0) {
                        $scope.condition = "if";
                        $scope.photoRecordsTotal = $scope.photosCount;
                    } else {
                        $scope.condition = "else";
                    }
                    if (selectedTab === "edit_album") {
                        $scope.doToggleSelectAll($scope.checkAllFlag, $scope.photoRecordsOffset);
                    }
                    // Get Emoji list
                    // if (!!HzPhotoService.getSharedEmojis()) {
                    if (0 === Object.keys($rootScope.emojis).length) {
                        $scope.doEmojiList();
                    }
                    console.timeEnd("albumprocess");
                },
                function (res) {
                    $scope.flag = false;
                    /*
                     * Error hading in repsonse
                     */
                    var data = {album: {count: $scope.albumsCount, data: $scope.albums}, albumsWithDeletedPhoto: {count: $scope.albumsWithDeletedPhotoCount, data: $scope.albumsWithDeletedPhoto}, myAlbum: {count: $scope.myAlbumsCount, data: $scope.myAlbums}, myAlbumWithDeletedPhoto: {count: $scope.myAlbumWithDeletedPhotoCount, data: $scope.myAlbumWithDeletedPhoto}, photo: {count: $scope.photosCount, data: $scope.photos}};
                    HzPhotoService.setSharedData(data);
                    notifications.showSuccess({
                        message: "Oops! something went wrong, please try again later.",
                        hideDelay: 3000, //miliseconds
                        hide: true // boolean
                    });
                })
                .catch(function (response) {
                    console.error('request error', response.status, response.data);
                })
                .finally(function () {
                    console.log("finally finished request");
                });
    };
    }

    angular
        .module("AppDream")
        .controller('PhotoCtrl', ['$rootScope', '$scope', '$state', '$window', '$routeParams', '$timeout', 'HzServices', 'HzPhotoService', 'Upload', 'HzSocket', 'notifications', PhotoCtrl]);
}());

公共服务

(function () {
    'use strict';
    angular
        .module("AppDream")
        .factory("HzServices", ['$rootScope', '$http', '$cacheFactory', '$q', '$location', 'notifications',
            function ($rootScope, $http, $cacheFactory, $q, $location, notifications) {
                return {
                    /**
                     * Common $q reponse
                     * @param {type} url
                     * @param {type} method
                     * @param {type} data
                     * @returns {object}
                     * @description Common method to get ajax response via $q api
                     */
                    deferred: function (url, method, data) {
                        var req = {
                            method: method,
                            url: url,
                            headers: {
                                'Content-Type': "application/json"
                            },
                            cache: false
                        };
                        if ("GET" === method.toUpperCase()) {
                            req.params = data;
                        } else if ("POST" === method.toUpperCase()) {
                            req.data = data;
                        } else {
                            req.data = "";
                        }

                        var deferred = $q.defer();
                        $http(req)
                                .success(function (data, status, headers, config) {
                                    deferred.resolve(data);
                                })
                                .error(function (data, status) {
                                    deferred.reject(data);
                                });
                        return deferred.promise;
                    },
            }
        ]);
}());

延迟加载指令(滚动到分页)

angular
.app("AppDream",
.directive('hzLazyScroll', [
    '$rootScope',
    '$window',
    '$timeout',
    function ($rootScope, $window, $timeout) {
        return {
        link: function (scope, elem, attrs) {
            var scrollEnabled, loadData, scrollTrigger = .90, scrollEnabled = true;
            $window = angular.element($window);
            if (attrs.lazyNoScroll !== null) {
            scope.$watch(attrs.lazyNoScroll, function (value) {
                scrollEnabled = (value === true) ? false : true;
            });
            }
            if ((attrs.lazyScrollTrigger !== undefined) && (attrs.lazyScrollTrigger > 0 && attrs.lazyScrollTrigger < 100)) {
            scrollTrigger = attrs.lazyScrollTrigger / 100;
            }
            loadData = function () {
            var wintop = window.pageYOffset;
            var docHeight = window.document.body.clientHeight;
            var windowHeight = window.innerHeight//$window.height();
            var triggered = (wintop / (docHeight - windowHeight));
            if ((scrollEnabled) && (triggered >= scrollTrigger) && (triggered >= scrollTrigger)) {
                console.log("Lazy load applies");
                console.log("triggers>>>" + triggered);
                console.log("scrollTrigger>>>" + scrollTrigger);
                return scope.$apply(attrs.lazyScroll);
            }
            };
            $window.on('scroll', loadData);
            scope.$on('$destroy', function () {
            return $window.off('scroll', loadData);
            });
        }
        };
    }
]);

的index.html

<!DOCTYPE html>
<!--[if lt IE 7]>
  <html class="lt-ie9 lt-ie8 lt-ie7" lang="en">
  <![endif]-->
<!--[if IE 7]>
  <html class="lt-ie9 lt-ie8" lang="en">
<![endif]-->
<!--[if IE 8]>
  <html class="lt-ie9" lang="en">
<![endif]-->
<!--[if gt IE 8]>
<!-->
<html lang="en" ng-app="AppDream" class="no-js">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
    <meta name="MobileOptimized" content="320" />
    <meta name="description" content="Dream" />
    <meta http-equiv="Cache-control" content="public"/>
    <link rel="shortcut icon" href="/favicon.ico"/>
    <!-- All css dependencies -->
    </head>
    <body ng-controller="hzAppCtrl">
    <!-- <hz-loader></hz-loader> -->
    <!-- Site Template -->
    <notifications-bar class="notifications notification_position_set"></notifications-bar>
    <!-- Header section -->
    <header id="ccr-header" ui-view="globalHeaderLine1"></header>
    <!-- <section id="ccr-site-title" ui-view="globalHeaderLine2"></section> -->
    <div class="clear"></div>
    <div ng-class="remove_site_scroll_body_sticky === true ? 'padding_top5' : 'site_scroll_body'">
    <div class="container_video" ui-view="globalHeaderLine3"></div>
    <div class='fake-container' ui-view='globalHeaderLine4'></div>
    <div class="container" ui-view="globalHeaderLine5"></div>
    <div class="container" ui-view="globalHeaderLine6"></div>
    <div class="container" ui-view="globalHeaderLine7"></div>
    <div ui-view="featureBar"></div>
    <div ui-view="content"></div>
    <footer class="clear" ui-view="footer"></footer>
    <hz-scroll-top></hz-scroll-top>
    </div>
    <!-- All javascript depdendencies -->
</body>
</html>

app.routes.js

(function () {
    /**
     * Authentication interceptor intercepts authentication requests and validate requests.
     * @param {type} $window
     * @param {type} $cookies
     * @returns {Object}
     */
    function authInterceptor($window, $cookies) {
    return{
        request: function (config) {
            //console.log("Interceptor called");
            if ("" !== $cookies.get('hz-token') && null !== $cookies.get("hz-token") && undefined !== $cookies.get("hz-token")) {
                config.headers.Authorization = 'Bearer ' + $cookies.get('hz-token');
            }

            return config;
        },
        responseError: function (rejection) {
            console.log("rejection");
            console.log(rejection);
            // do something on error
            var errorCode = rejection.status;
            if (401 === parseInt(errorCode)) {
                $window.location.href = "/";
            } else if (parseInt(rejection.status) === -1 || parseInt(rejection.status) === -2) {
                return rejection;
            } else if (200 !== parseInt(errorCode)) {
                $window.location.href = "/#/error/" + errorCode;
                ///$state.go("app.error", {code: errorCode});
            }
        }
    };
    }

    /*
     * Default Route of application
     * @param {$stateProvider} Object
     * @param {$routeProvider} Object
     * @return
     */
    function config($stateProvider, $urlRouterProvider, $httpProvider, $provide) {
    $urlRouterProvider.otherwise('home');
    $httpProvider.defaults.withCredentials = true;
    $provide.factory('GlobalAjaxInterceptor', ['$q', '$rootScope', globalAjaxInterceptor]);
    $provide.factory('AuthInterceptor', ['$window', '$cookies', authInterceptor]);
    $httpProvider.interceptors.push('AuthInterceptor');
    $stateProvider
            .state('app', {
                url: '/',
                views: {
                    'globalHeaderLine1': {templateUrl: '/partials/headerLine1.html', controller: 'SigninCtrl', controllerAs: 'Signin'},                
                }
            })
            /*
             * Error page
             */
            .state("app.error", {
                url: "error/:code",
                views: {
                    'content@': {templateUrl: '/partials/error.html', controller: 'ErrorCtrl', controllerAs: 'Error'}
                }
            })
            .state('app.home', {
                url: 'home',
                views: {
                    'globalHeaderLine3@': {templateUrl: '/partials/headerLine3.html', controller: 'HomeCtrl', controllerAs: 'Home'},
                    'globalHeaderLine4@': {templateUrl: '/partials/headerLine4.html'},
                    'globalHeaderLine5@': {templateUrl: '/partials/headerLine5.html'},
                    'globalHeaderLine6@': {templateUrl: '/partials/headerLine6.html'},
                    'globalHeaderLine7@': {templateUrl: '/partials/headerLine7.html'},
                    'content@': {templateUrl: '/views/home/home.html', controller: 'HomeCtrl', controllerAs: 'Home'}
                }
            })
            .state("app.photos", {
                url: ":pid/photos",
                params: {
                    pid: 'me'
                },
                views: {
                    'content@': {templateUrl: '/views/photo/photo.html', controller: 'PhotoCtrl', controllerAs: 'Photo'}
                }
            });

    }

    angular
        .module('AppDream')
        .factory('authInterceptor', ['$window', '$cookies', authInterceptor])
        .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', '$provide', config])
        .run(["$rootScope", "$http", "$location", "$state", "$stateParams", "HzServices", "UserService", function ($rootScope, $http, $location, $state, $stateParams, HzServices, UserService) {
                HzServices.getDirectories();
                $rootScope.recordsPerPage = 20;
                $rootScope.recordsOffset = 0;
                $rootScope.recordsTotal = 0;
            }]);
}());

Photo.html

<div class="container">
    <div class="container_main">
    <hz-left-side></hz-left-side>
    <div class="containarea_right">
        <div class="tab_top_tab">
            <div ng-include="'/views/photo/settings.html'"></div>
        </div>
        <div class="middle-first-row-tab-out" ng-class="{newsfeedtab: (pid === 'me' || pid !== 'me' && photosCount > 0)}">
            <div class="tabs-container" id="tab-container">
                <div class="tabs-frame-content tab_content innerpagetab" id="all-photos" ng-if = "currentTab === 'all-photos'">
                    <div ng-include="'/views/photo/allPhotos.html'"></div>
                </div>
            </div>
        </div>
    </div>
    </div>
</div>
<div class="contail_area"></div>
<div class="clear"></div>

allPhotos.html

<div class="tab_left" >
    <div class="keyword margin_top margin_bottom float_left fullwidth">        
    <div ng-if="photos.length > 0 && currentTab === 'all-photos'" hz-lazy-scroll lazy-scroll="doAlbumList('VIEWMORE', myAlbumId)" lazy-scroll-trigger="60" lazy-no-scroll="photos.length > 0 && photoRecordsTotal > 0 && photos.length === photoRecordsTotal">
    <hz-browse-photo
        photos="photosByDate"
        message=""
        myAlbums="albums"
        ng-model="photoModel"
        photo-options="0"
        current-tab="currentTab">
    </hz-browse-photo>
    </div>
    <div hz-no-photos-message photos-count="photoRecordsTotal" flag="flag" album="myAlbum" my-album-auto-generated='myAlbumIsAutoGenerated'></div>
</div>

0 个答案:

没有答案