Reputation: 6797
I would like to use the ngInfiniteScroll
directive from here: http://binarymuse.github.io/ngInfiniteScroll/ in my angular js app to implement a reverse infinite scroll (like in a chat widget). However the documentation for this directive does not seem to mention how this can be accomplished. It only documents how the standard infinite scroll is implemented. Could someone guide me in this regards? Thanks!
P.S : I'm keen on using this directive since it deals with the DOM control; the standard infinite scroll directive from angular keeps creating DOM elements as I scroll which is never deleted.
Upvotes: 7
Views: 8051
Reputation: 6916
you can use this zInfiniteScroll project on github, it make you scroll down to end or scroll up to top for update feeds.
if you want to add auto scroll down when received message, bind this ngSmoothScroll project
here is use example:
<body ng-app="myApp" ng-controller="mainCtrl">
<div z-infinite-scroll="loadOlder" inverse="false" body-scroll="true">
<div smooth-scroll scroll-if="{{$last}}" duration="0" ng-repeat="obj in messages">
{{obj.message}}
</div>
</div>
</body>
this is demo for you from plunker
it will received message 10 seconds, and if you scroll to top that history will be loaded.
Upvotes: 2
Reputation: 2620
I think you should rather have a model based approach (which fits particularly to angular) ie when you scroll up and reach a limit, you load more data and insert them at the beginning of your messages collection (you could also remove the most recent if you want to limit the amount of html nodes loaded for performance reason).
This is the kind of approach I have used with lrInfiniteScroll
There is no dom manipulation at all, it just detects when you scroll down and reach the bottom (with a debounce) and trigger an handler you have bound so you can do whatever you want, and particularly change your model: your application remains model driven
I have change the logic a bit to have the scroll up behavior, but the idea remain the same
(function (ng) {
'use strict';
var module = ng.module('lrInfiniteScroll', []);
module.directive('lrInfiniteScroll', ['$timeout', function (timeout) {
return{
link: function (scope, element, attr) {
var
lengthThreshold = attr.scrollThreshold || 50,
timeThreshold = attr.timeThreshold || 400,
handler = scope.$eval(attr.lrInfiniteScroll),
promise = null,
lastScrolled = -9999;
lengthThreshold = parseInt(lengthThreshold, 10);
timeThreshold = parseInt(timeThreshold, 10);
if (!handler || !ng.isFunction(handler)) {
handler = ng.noop;
}
element.bind('scroll', function () {
var scrolled = element[0].scrollTop;
//if we have reached the threshold and we scroll up
if (scrolled < lengthThreshold && (scrolled - lastScrolled) < 0) {
//if there is already a timer running which has no expired yet we have to cancel it and restart the timer
if (promise !== null) {
timeout.cancel(promise);
}
promise = timeout(function () {
handler();
//scroll a bit againg
element[0].scrollTop=element[0].clientHeight/2;
promise = null;
}, timeThreshold);
}
lastScrolled = scrolled;
});
//scroll first to the bottom (with a delay so the elements are rendered)
timeout(function(){
element[0].scrollTop=element[0].clientHeight;
},0);
}
};
}]);
})(angular);
And a running example
Upvotes: 6