こんにちは。今日は暖かい日和です。もう3月ですね。
さて、放置気味だったAngularJSの勉強を再開しました。
とりあえずこの本を読んでいます。
良い本と思います。
さて、Twitterのタイムラインのような無限スクロールをAngularJSで作るとどういう感じになるのかな、ということを調べてみました。
ググってみると、ズバリなものが見つかります。
ngInfiniteScroll
これでええやん、という話ですが、今回はもっと軽い実装を探してみます。
そうすると、こういうものがJSFiddleにアップされています。
AngularJS: Infinite Scrolling
なるほど、AngularJSではコレクションのレンダリングは自動でやってくれるので、一番下までスクロールしたタイミングでコレクションにデータを追加してやれば簡単にできるようです。
これを参考にして実装してみました。
Template
無限スクロールを表示する部分です。
<div class='content' when-scrolled='loadMore()'>
<ul ng-repeat='d in data'>
<li>{{d}}</li>
</ul>
</div>
|
dataという名前のコレクションをリスト表示しています。
リストを囲っているdivにwhen-scrolledというディレクティブを指定しています。
Directive
whenScrolledディレクティブです。
一番下までスクロールしたらattributeの値を実行するようにします。
つまりコントローラーのloadMoreを実行します。
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}])
.directive('whenScrolled', function($window) {
return function(scope, elem, attr) {
var raw = elem[0];
angular.element($window).bind('scroll', function() {
if (raw.offsetTop + raw.offsetHeight < document.documentElement.scrollTop + window.innerHeight) {
scope.$apply(attr.whenScrolled);
}
});
};
});
|
Controller
コントローラーはInfiniteScrollCtrlです。
初期時には25個の要素をdataに入れます。
loadMoreメソッドがコールされると、dataに25個追加します。
これにより無限スクロールするように見えます。
angular.module('myApp.controllers', []).
controller('MyCtrl1', [function() {
}])
.controller('MyCtrl2', [function() {
}])
.controller('InfiniteScrollCtrl', ['$scope', function($scope) {
var i = 0,
data = [];
for(i = 0; i < 25; i++) {
data.push(i);
}
$scope.data = data;
$scope.next = data.length;
$scope.loadMore = function() {
if ($scope.next === i + 25) {
return;
}
$scope.next = i + 25;
for(; i < $scope.next; i++) {
data.push(i);
}
};
}]);
|
まとめ
データを増やせば自動でレンダリングされるので、jQueryなどで実装するよりコード量が減りますね。
ここに実装おいてます。