我正在尝试在鼠标滚动事件上实现服务器端分页,以便在滚动到达页面/ 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();
}
});
我经常尝试找出原因,但没有运气。这可能是我做错了。有人可以帮我解决这个问题吗? 任何帮助/建议都提前感谢。
答案 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概念来完成。以编程方式实现此逻辑将是一个好主意。