AngularJS Server侧面分页鼠标滚动指令事件两次调用

时间:2015-04-18 07:34:28

标签: angularjs angularjs-directive

我正在尝试在鼠标滚动事件上实现服务器端分页,以便在滚动到达页面/ div底部时加载数据。我做了一些研究,发现有很多选择,比如ngInfiniteScroll等。

有了这个,我还发现了几个小提琴做了同样的事情,没有任何第三方js依赖,如下面的链接所示 -

AngularJS Server side pagination on mouse scroll

http://jsfiddle.net/akagr/Eu2FW/4/light/

http://jsfiddle.net/vojtiik/n2NHL/

我创建了一个POC,引用了最后一个链接,即http://jsfiddle.net/vojtiik/n2NHL/,它在POC中也可以正常工作。

以下是我实施的POC代码。为方便起见,我对它进行了一些修改,但概念是一样的:

Index.html文件:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="myApp">
<head>
    <title></title>
    <script src="Scripts/JS/angular.js"></script>
    <script src="Scripts/JS/angular.min.js"></script>
    <script src="Scripts/JS/jquery.min.js"></script>
    <script src="Scripts/ngInfiniteScroll/ng-infinite-scroll1.2.0.js"></script>
    <script src="Scripts/ngInfiniteScroll/ng-infinite-scroll1.2.0.min.js"></script>
    <script src="Scripts/JS/angular-route.min.js"></script>
    <script src="app/app.js"></script>
    <script src="app/Controllers/mainCtrl.js"></script>
    <style>
        li {
            height: 120px;
            border-bottom: 1px solid gray;
        }

        #fixed {
            height: 400px;
            overflow: auto;
        }
    </style>

</head>
<body data-ng-controller="mainCtrl">
    <div id="fixed" when-scrolled="loadMore()">
        <ul>
            <li ng-repeat="i in items">{{i.id}}</li>
        </ul>
    </div>
</body>
</html>

app.js文件:

var myApp = angular.module('myApp', []);
myApp.directive('whenScrolled', function () {

    return function (scope, elm, attr) {
        var raw = elm[0];
        var takeRows = scope.takeRows;

        elm.bind('scroll', function () {
            if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                // scope.$apply(attr.whenScrolled({ id: takeRows }));
                scope.loadMore(takeRows);
                scope.$apply();
            }
        });
    };
});

mainCtrl.js

myApp.controller('mainCtrl', ['$scope', '$rootScope', function ($scope, $rootScope) {
    $scope.items = [];

    var counter = 0;
    $scope.takeRows = 20;

    $scope.loadMore = function (takeRows) { //Not using takeRows parameter now. Will use it later.

        for (var i = 0; i < $scope.takeRows; i++) {
            $scope.items.push({ id: counter });
            counter += 10;
        }
    };

    $scope.loadMore();
}
]);

现在我的问题是我在我的应用程序中尝试了相同的代码 我看到了一个奇怪的问题。每当我的滚动到达底部时,我的指令就会被正确触发。但if条件满足两次并且它从指令触发loadMore()函数两次。条件如下代码所示 -

elm.bind('scroll', function () {
            if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                // scope.$apply(attr.whenScrolled({ id: takeRows }));
                scope.loadMore(takeRows);
                scope.$apply();
            }
        });

我经常尝试找出原因,但没有运气。这可能是我做错了。有人可以帮我解决这个问题吗? 任何帮助/建议都提前感谢。

1 个答案:

答案 0 :(得分:0)

这意味着你的元素绑定了scroll个事件两次,你可以确保事件在绑定之前仅通过unbind滚动事件绑定一次。

<强>代码

ele.unbind('scroll');
elm.bind('scroll', function() {
    if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
        // scope.$apply(attr.whenScrolled({ id: takeRows }));
        scope.loadMore(takeRows);
        scope.$apply();
    }
});

<强>更新

除了此代码之外,如果正在进行任何服务调用,则scope.loadMore(takeRows)不应调用该服务,这可以使用promises概念来完成。以编程方式实现此逻辑将是一个好主意。