如何在没有 JQuery 的情况下正确实现无限滚动的 AngularJS 表?

Uri*_*izu 4 javascript lazy-loading infinite-scroll angularjs

我有一个 AngularJS 项目(我不使用 JQuery),我需要在其中显示一个包含用户的表格,并在用户滚动到页面末尾附近时加载更多内容。我试图在不依赖外部库的情况下实现这一点,因为这是我的要求的一部分。

我检查了几个例子像这个这个这个

但到目前为止,我检查过的所有示例都没有帮助我实现我预期的无限滚动。他们使用不同的方法来计算何时触发调用,其中一些值返回给我未定义(即人们说 clientHeight 和 scrollHeight 有不同的值,但对我来说它总是相同的,包括滚动空间的总高度)。

我创建了一个如下所示的指令:

usersModule.directive('whenScrollEnds', function($window) {
    return {
        restrict: "A",
        link: function(scope, elm, attr) {

          angular.element($window).bind('scroll', function() {

            var hiddenContentHeight = elm[0].scrollHeight - angular.element($window)[0].innerHeight;

            if ((hiddenContentHeight - angular.element($window)[0].scrollY) <= (10 )) {
              angular.element($window)[0].requestAnimationFrame(function(){
                scope.$apply(attr.whenScrollEnds);
              })
            }

          });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

这种工作,但有以下问题/疑问,我希望有人能向我解释:

  • 触发太快了。我希望在接近可滚动空间的底部时触发加载,例如接近 90% 左右。
  • scrollHeight 只能通过 elm[0] 访问,angular.element($window)[0] 没有 scrollHeight 属性所以它返回 undefined,而 elm[0] 没有 scrollY 值。
  • 我得到的 scrollY 值是滚动条从顶部移动的距离减去滚动条长度,但我觉得这个值是错误的。
  • 通过 angular.element($window).bind 绑定滚动事件是否正确?

如何实现适当的无限滚动表?我是否使用了正确的变量?请提供仅使用 Javascript 和 AngularJS 的答案,JQuery 或库解决方案对我没有帮助。

Uri*_*izu 5

在检查了几个示例并试图避免使用 JQuery 作为解决方案的一部分之后,我找到了一种方法来使这项工作发挥作用。

首先我的指令将在滚动结束时处理:

usersModule.directive('whenScrollEnds', function($window) {
    return {
        restrict: "A",
        link: function(scope, elm, attr) {
          var raw = elm[0];

          raw.addEventListener('scroll', function() {
            if ((raw.scrollTop + raw.clientHeight) >= (raw.scrollHeight )) {
                scope.$apply(attr.whenScrollEnds);
            }
          });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

我的视图中有这样的表div

  <div id="usersScrollable" when-scroll-ends="uc.loadMoreUsers()">
    <table id="tableUsers" class="table" ng-show="uc.users.length" >
      <thead>
      <tr>
        <th>Email</th>
        <th>Nombre Completo</th>
        <th>Estado</th>
        <th>Acción</th>
      </tr>
      </thead>
      <tbody >
      <tr ng-repeat="u in uc.users">
        <td>{{u.email}}</td>
        <td>{{u.fullName}}</td>
        <td>{{uc.getStateString(u.active)}}</td>
        <td><button type="button" class="btn btn-primary" ng-click="uc.edit(u)">Editar</button></td>
      </tr>
      </tbody>
    </table>
  </div>
Run Code Online (Sandbox Code Playgroud)

确保div包含表格的内容是滚动结束时正在收听的内容。这div必须有一个设置的高度,如果没有,那么clientHeight属性将与scrollHeight(不确定如果没有明确定义高度会发生什么,比如设置顶部或底部属性而不是设置高度)。

在我的控制器中,loadMoreUsers()负责增加页面(如果有更多用户,我得到的每次调用都有用户总数,所以我可以在发出另一个请求之前知道我还剩下多少用户),它还调用了使对 Web 服务的请求。