ng-infinite-scroll

2015-06-19T00:00:00+09:00 JavaScript angular.js

公式: https://sroze.github.io/ngInfiniteScroll

スクロールによるページング処理に関してみたいな事をangular.jsでやってくれるライブラリがng-infinite-scrollっていうのがあるのでさらっと使ってみた

index.html

<!DOCTYPE html>
<html ng-app="sample">
  <head>
    <script src="jquery.js"></script>
    <script src="angular.js"></script>
    <script src="ng-infinite-scroll.js"></script>
    <script src="app.js"></script>
  </head>
  <body ng-controller="InfiniteScrollCtrl">
    <div>
      <div infinite-scroll="nextPage()"  infinite-scroll-distance="0"></div>
      <div ng-repeat="sample in samples">
        <h4>{% raw %}{{sample}}{% endraw %}</h4>
      </div>
    </div>
  </body>
</html>

infinite-scrollでスクロールが起きた場合に発生する処理を指定出来る。この場合には$scope.nextPageがコールされる

app.js

angular.module('sample', ['infinite-scroll'])
  .controller(
    'InfiniteScrollCtrl',
    [
      '$scope', '$timeout', '$http', '$window',
      function($scope, $timeout, $http, $window) {
        $scope.page = 0;
        $scope.samples = [];

        $scope.nextPage = function() {
          $timeout(function() {
            $scope.page++;

            $http.get('/page/' + $scope.page + '.json')
              .success(function(res) {
                $scope.samples = $scope.samples.concat(res);

                // ここらで一定のページ数に達したら以下のエラー時同様にscrollイベントを止めるとかもありかと
              })
              .error(function(err) {
                // 通信エラーが起きたらscrollイベントを解除
                angular.element($window).off('scroll');
              });
          });
        };
      }
    ]
  );

てな感じで使えばスクロールにより末尾に達した際に$httpでデータを取得して追加、エラー時にはscrollイベントを停止させるような処理が出来る。ちなみにng-infinite-scroll.jsでは

scope.$on('$destroy', function() {
  return $window.off('scroll', handler);
});

っていうように$destroyイベントを$scopeでぶん投げてもscrollイベントを解除出来る(あくまで上記ng-infinite-scroll.jsのコードはproduction版のやつ)。又、infiniteScrollDisabledっていう属性をwatchするようになっているので

<div infinite-scroll="nextPage()" infinite-scroll-disabled="busy">
</div>

のようにinfinite-scroll-disabledを使ってプロパティでロックして多重に処理されないような仕組みを取る事も出来る模様(詳しくは https://sroze.github.io/ngInfiniteScroll/demo_async.html )

angular.js directiveのbindToController MockWebServerRule