今回もAngularネタです。
一般的なデータの一覧画面ではページャーをボタンで移動するのではなく、スクロールするだけで次々とアクセスできるようになるのが一般的でしょう。
facebookやtwitterなどが一般的ですね。
そんなときに使えるのがngInfiniteScrollというライブラリです。
インスト-ル
bowerに下記のように記述してあげればOKです。(2017年6月現在1.3.4が最新です。)
1 2 3 |
"dependencies": { "ngInfiniteScroll":"^1.3.4", } |
バージョンが古い(具体的には1.0.0以前)場合、後述するような不具合が起こります。
ソース
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<html lang="ja" > <head> <meta charset="UTF-8"> <title>sample</title> <link rel="stylesheet" href="./bower_components/bootstrap/dist/css/bootstrap.min.css"> <script src="./bower_components/angular/angular.min.js"></script> <script src="./bower_components/ngInfiniteScroll/build/ng-infinite-scroll.min.js"></script> <script src="./js/infinite_scroll2.js"></script> <body> <div ng-app="myApp"> <div style="height:600px;" ng-controller="infiniteScroolCtrl"> <div infinite-scroll="getZip()" infinite-scroll-disabled='isLoaging' infinite-scroll-distance="0" > <div ng-repeat="item in items"> {{item.id}} {{item.zip}} : {{item.address1}} {{item.address2}} {{item.address3}} </div> </div> </div> </div> </body> </html> |
JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//ここでinfinite-scrollを読み込む //またTHROTTLE_MILLISECONDSを記述しておかないと少しのスクロールで大量の読み込みが起こってしまいます。 var app = angular.module("myApp", ['infinite-scroll']).value('THROTTLE_MILLISECONDS', 500); //ここでJSONを吐き出すURLにアクセスします。offset句を付けることでレコードの読み込み開始点を設定します。 app.factory('loadZip',function($http){ return { getAddress:function(offset){ return $http.get('JSONを吐き出すURL句' + offset ).then(function(data){ return data; }); } } }); app.controller('infiniteScroolCtrl', function( $scope, loadZip ){ $scope.offset = 0; $scope.isLoading = false; $scope.items =[]; $scope.getZip = function(){ //loadingを止める $scope.isLoading = true; loadZip.getAddress( $scope.offset ).then(function(res){ for(var i = 0; i < res.data.length; i++) { $scope.items.push(res.data[i]); } var length = $scope.items.length; //吐き出されたデータの最後部のidを取得しoffset句とする。普通に $count++などとやったほうが適切かも $scope.offset = $scope.items[length-1]['id']; //loadingしてもよい $scope.isLoading =false; }); }; }); |
説明
非常にシンプルでスクロールをし、スクロール量が画面下に達した時点で読み込みが始まります。
infinite-scroll 実際に発火されるメソッド
infinite-scroll-disabled trueのときはメソッドが発火しません。使いどころとしてはある処理を読み込んでいるときは多重読み込みになってしまうので、読み込みが始まった時点でtrueにし、データを読み込んだ時にはfalseにします。
infinite-scroll-distance スクロールを検知する画面サイズの定義のようです。0の場合ブラウザの底辺になります。
var app = angular.module(“myApp”, [‘infinite-scroll’]).value(‘THROTTLE_MILLISECONDS’, 500);
上記はリクエストが発生し、次のリクエストが発生するまでの最低の間隔です。
これを書かないとスクロールした瞬間に大量のリクエストが発生します。
上記のisLoadingも役に立たななかったです。(最初のリクエストの処理が始まってisLoadingが始まる前にすでに複数のリクエストが呼ばれてしまっている。)
(0.5秒であれば最初の読み込みが始まり、$isLoadingに達成するまでに十分時間がもちます。)
ちなみに1.0.0以降でないと有効にはないっていないのでバージョンには気を付けましょう。