angular-ui / ui-scroll Goto Github PK
View Code? Open in Web Editor NEWUnlimited bidirectional scrolling over a limited element buffer for AngularJS applications
Home Page: http://angular-ui.github.io/ui-scroll/demo/
License: MIT License
Unlimited bidirectional scrolling over a limited element buffer for AngularJS applications
Home Page: http://angular-ui.github.io/ui-scroll/demo/
License: MIT License
I'm a befuddled. In this simple example, the scroller is loading 7 "pages" worth of data initially and then when I scroll down the load one more page, scrolling up gets very confused, jumping from the 70's to the 50's to the 30's.
https://github.com/marknadig/ui-scroll-test/tree/master/forward-only
So, first questions.
Related, I'm trying to make the scroller in this case forward-only so that it only loads fro index > 0. If I scroll down until it loads another page and then up to the very top, it starts making requests for very large indexes.
Last question: Is this even possible? If so, is this the right approach?
Is there a way to retrieve the elements that are currently in the buffer? Or have a callback when they are added? I use a dotdotdot directive to truncate texts but that one only works if the elements are visible.
So on the first page everything is fine, but the next page my directive fires to early.
Right now visibilityWatcher is being triggered only during angular digest cycle (wrapper.scope.$watch). So if we have a delayed rendering of the ui-scroll contents (with 0 height right after insert) then no adjustBuffer call occures till digest cycle isn't started.
<a ui-scroll="subject in subjects" adapter="myAdapter" ng-show="myAdapter.isLoading">
This kind of markup breaks new elements fetching, only one package comes to the view before something initiates a new digest cycle.
The current commit on the master branch doesn't have the get(descriptor, success)
implementation for the datasource. If this is intentional, will you please let me know the reason? If it isn't, just let me know, and I will submit an pull request for it.
Hi,
I see a bug in demo examples like persistentScroll and positionedList, when the start of list is known not unlimited. By adding some log to the code and monitoring index value, I found that after scrolling down, when want to get back up, there is a place that list items jump down. For example you are on item 32 and are going up to 31, 30, 29, and suddenly it jumps to 32 again and this is the place where the index value has found negative value. If the count value be more than 10 like 20 the jump is more clear. The place where the jump happens is different base on the position of scroll and not the same place every time. But the place where the jumps happened is exactly when while going up, scroll position is positive and index value gets negative.
First of all, ui-scroll is great!
It improves the performance significantly.
Is there a way to keep the rows till the reload finishes and the datasource comes back with new / refreshed data? Currently, the rows are removed instantly when I'm calling reload().
Hi, I'm trying to reload just as the animation example demo.
I get the following error:
TypeError: $scope.adapterContainer.adapter.reload is not a function
v1.3.3
$scope.refresh = function () {
return $scope.adapterContainer.adapter.reload();
};
Wondering if it is different in 1.3.3?
This will allow use cases where ui-scroll-start and ui-scroll-end are required (for me, when rendering tables with conditions on what tr to render)
So I'm using the get function with descriptor and append/prepend logic that we talked about in #63 and I have some weird jogging (race conditions) going on and I not sure if I'm interpreting the logic based on what is being called. I'm loading an object array lets call it posts and buffer size is 20. I should note that about 5 posts fit on a page, so I want to load up 20 at a time. It loads the first twenty fine, but when I scroll down, it looks like its calling for the next twenty which is correct, but immediately calls for the previous twenty starting from the current position -3 (which is the internal buffer overlap I guess).
So problem (a) - why do we need load the previous items that we already have?
Problem (b) seems to be this race condition where it calls get for the next twenty and previous 20 in a loop but offset each time. Here's the console results.
page load
load count(20), index (1), append(undefined), prepend(undefined) : 20 loaded first time - perfect
load count(20), index (-19), append(undefined), prepend(id:179) : 0 loaded - perfect
user scrolls down 20
load count(20), index (21), append(id:43), prepend(undefined) - next 20 perfect
load count(20), index (-3), append(undefined), prepend(id:97) : 16 loaded - problem (a)
load count(20), index (19), append(id:96), prepend(undefined) : 20 loaded - problem (b)
load count(20), index (-4), append(undefined), prepend(id:104) : 15 loaded - problem (a/b)
.
.
...and so on... I hope you can find that I'm doing something wrong. A few questions.
Here is the code I used to do cursor scrolling of results - it seems like the right approach, just not sure why this version of get is calling me in this fashion.
var feedsource;
feedsource = {};
feedsource.get = function (descriptor, success) {
var max_id, since_id;
if (descriptor.append) {
max_id = descriptor.append.aId;
}
if (descriptor.prepend) {
since_id = descriptor.prepend.aId;
}
console.log('load count(' + descriptor.count + '), index (' + descriptor.index + '), append(' + max_id + '), prepend(' + since_id + ') ');
loadFeedCursor(descriptor.count, max_id, since_id).then(function (resp) {
console.log(':' + resp.items.length);
return success(resp.items); // array of my json objects - assuming this is okay
});
};
<div ui-scroll-viewport fill-height>
<ul class="list-group list-group-sm no-radius m-b-none m-t-n-xxs">
<li ui-scroll="post in feedsource" buffer-size="20" class="list-group-item clearfix b-l-3x" adapter="feedAdapter.adapter">
<div ng-include="'tpl/feed.detail.post.html'"></div>
</li>
</ul>
</div>
Marty
I'm trying to dynamically add stuff to the bottom (for a chat thread which is displayed by ui-scroll). However it seems that using appleUpdates
on the adapter doesn't do anything. Using reload()
works but it's not an acceptable solution (causes jumps and reloads all the time).
Isn't it possible to append elements at the end of list?
I'm receiving the following error: TypeError: Cannot read property 'reload' of undefined, when I call $scope.adapter.reload();
ui-scroll is used inside a tbody:
<tbody ui-scroll="transaction in bt.datasource" adapter = "adapter" buffer-size="10" padding="0.3">
I would like to be able to 'reload' the infinite scroll list at a certain point in the list.
Something like adapter.reload({startIndex: 12}) to load the list starting at location 12
I played around with this in the ui scroll code and got this working without changing a lot of code. Is this something that it would make sense to (clean, test, and then...) submit a pull request for?
I'm wondering if anyone has been able to make this module work using page #/page size API calls? The API i'm plugging into requires these instead of index & offset. Calls when scrolling down are obvious & easy, but because of the way the buffer clears itself, I haven't found a way to make it work when scrolling up. Could the buffer functionality be changed to remove whole chunks instead of half?
Hi, I just noticed that this project is not available on npm or bower. Is the code in this repo production ready? Any timeline on when they're going to be put on npm/bower?
Hi
In my current project we heavily rely on ui-scroll component and we need it to have good performance characteristics and be stable.
Currently there's a big problem with performance #45
I'd like to deal with it and fix other issues I found after revising the code.
But there is a problem - the code is written in coffeescript.
I don't know it much and therefore it's hard to read it and refactor.
The question is could we use plain js (ES Harmony)?
I'm sure it would make a boon to the component and attract more developers to make their contributions.
I used ui-scroll for li elements, which are also annotated with ng-class. Then the ng-class is not correctly evaluated.
<li ui-scroll="elm in datasource" ng-class="{'selected-elm': isSelected(elm)}"></li>
If the ng-class is used in a sub element, everything works as expected
<li ui-scroll="elm in datasource">
<div ng-class="{'selected-elm': isSelected(elm)}">
</div>
</li>
Is there any reasoning behind this?
The problem is ui scroll starts loading from index 1, then shortly after prepends the element at index 0. This results in the container being scrolled down slightly on initial page load.
I tried just subtracting 1 from index before fetching elements from my array, but this can result in a situation where the requested index is -10 and count is 10 (total 0 elements requested) which means it will stop asking for more.
Hi
I've met strange behaviour of ui-scroll directive.
For example, if I have the following markup:
<li ui-scroll="item in datasource">{{log(item)}}</li>
then
{{log(item)}}
is evaluated before first call of datasource.get
method, thus item in this call is undefined
.{{log(item)}}
is evaluated with strange item undefined
, that doesn't exist.So the question is - why expression {{log(item)}}
is evaluated for strange item undefined
that doesn't exist?
I prepared plunk that shows this behaviour http://plnkr.co/edit/uotXYdrCCZlpmYNaX3Re?p=preview
With the recent improvements, the top visible item is no longer updated on scrolling. It is only updated when a call is made to the buffer because the calculateProperties function is now only called if the adjustBuffer is called. This is no longer called by default on the scroll event. Please see the link for a reproduction. If you scroll, the number should change when the top visible item is changed. You can see it only changes when new items are fetched from the datasource.
https://jsfiddle.net/ypdbmrt8/14/
I am working on a pull request right now. I am thinking that we should run the calculateProperties function in the resize scroll handler if the pending.length is not greater than 0.
I created a Definitely Typed type file for ui-scroll
https://github.com/marknadig/DefinitelyTyped/tree/nadig/angular-ui-scroll
basically just defined ng.ui.IScrollAdapter and ng.ui.IScrollDatasource
I would love your feedback before I submit this PR to the DT repo.
The story of inline and float-left elements is still not over.
Just run this demo and try to scroll up.
It seems the demo for inline blocks is not functional: http://angular-ui.github.io/ui-scroll/demo/examples/windowviewportInline.html
Also, I may be missing something, but I can't find a way to disable upward scrolling.
My situation is basically the same as the inline block demo, except I don't want to allow the index to drop below 1, and the items are coming from an api call.
Hi, I want to apply updates to a single object but the examples assume static indexes. Is there a way to pass $index like in ng-repeat? So I can say ng-click="update(item, $index)" so I can do an adapter.applyUpdates? Didn't see anything documented and hoping this is in there already just don't know how to do it. I know I have to essentially find the item in the result array and then update it but not sure if the adapter has a way to 'find' an object. Maybe that is the get method but not sure how to use it? Sorry, newble on some of this. I love the potential for this.
thanks
Marty
For example in one of the demos:
http://angular-ui.github.io/ui-scroll/demo/examples/tableScroller.html
If you scroll down a good amount of items and quickly move the scrollbar all the way to the top it will call success on the items in between. If you have enough items you will see that it will take a very long time to load. Is there any way around this?
Hi guys, I've been experiencing some random adapter reload issues and at first I thought it was just something I'm not doing right. Wondering if you can take a look at this repro. If you scroll down the list a few ways after append is called (buffer = 15), and click on reload, it sometimes does not return the list to the top. I also notice in this repro the first couple times, view port also does not fill up.
https://jsfiddle.net/MartyBolton/wf7o0ded/3/
Here's essentially all I'm doing in my app and repro. Wondering if I'm doing something wrong here. I didn't see any reload examples in demo.
thanks
Marty
html
<li ui-scroll="item in datasource" buffer-size="15" ng-class="{'odd': item.id % 2}" style="height:{{useIrregularHeight ? item.size + 22 : 150}}px;" adapter="feedAdapter.adapter">
// adapter implementation
$scope.feedAdapter = { adapter: { remain: true } };
$scope.reload = function() {
console.log ('reloading');
$scope.feedAdapter.adapter.reload();
}
I use ui-scroll to display a list of items from the database. The problem is that the entries in the database can get deleted at any time. Entries not only from the end of the database table, but from the middle as well.
This makes my database table not good for ui-scroll, as it (ui-scroll) is now. Because if I'm displaying database ids 11 to 20 (with index 11 to 20, say), and then entry 5 gets deleted, and then the user scrolls down, then when the browser requests entries with index 21 to 30, it is not going to get database ids 21 to 30, but 22 to 31. Because the SQL query will contain LIMIT 10 OFFSET 21
, but element 5 is missing, therefore ids 22-31 will be returned instead of ids 21-30, therefore id 21 will not appear at all in the viewport.
How do you solve this with the current ui-scroll? I think you can't. Mind you, you can't create an SQL like WHERE id BETWEEN 21 AND 30
because ids are rarely contiguous, there are huge gaps (of size n * 1000) between ids.
What is needed to fix this situation, I propose, is allow the developer to optionally declare a different get method, say relGet, that will allow (the new) ui-scroll to ask my application "give me the 10 items after the item with id 20" or "give me the 10 items before the item with id 10". I think that would solve all our problems.
What do you think?
I am facing a continual flicker of scroller, even after I have stopped scrolling on drawer. I don't getting the exact issue was but from log I can see, which subset the uiScroll is trying to load, it toggles between two sets extremely fast, and never stops. Please find video here: https://youtu.be/BRFlWgpCaE8
I am using v1.3.3 for ui-scroll.
Hi
Currently my app experiences big performance issues when scrolling through the list of items.
Having done some investigation I found out that each scroll event causes 2 digest cycles!!!
Taking into account that each digest cycle runs a lot of watchers (~1000) we are getting an unresponsive app.
It's a very bad idea by itself to do anything on every scroll event, even John Resig long time ago warned against using it http://ejohn.org/blog/learning-from-twitter/
But I wonder why do we need to run digest cycles at all when scrolling?
BTW, I found the way to get rid at list of one redundant digest call.
Look at this function
resizeAndScrollHandler = function() {
if (!$rootScope.$$phase && !adapter.isLoading) {
adjustBuffer();
return $scope.$apply();
}
};
$scope.$apply();
call here is redundant because adjustBuffer()
calls $timeout
function, which in its turn calls $scope.$apply();
. So we can get rid of $scope.$apply()
in the code above.
Would it be thinkable to add the feature (similar to clusterize.js) that the correct scroll position is shown if the total length of the list is shown?
Clusterize.js inserts a placeholder element on the top and one on the bottom with the height adjusted.
I ran into a weird issue where the list to be scrolled started to jump around crazily when new data was loaded (See here: refinery-platform/refinery-platform#852) and I figured out that this was caused by the following styling on list items:
li {
transition: height 0.2s ease;
}
It makes sense in a way as JS probably relies on the immediate application of the adjusted height of the first pseudo list item. A simple fix would be to disable transitions on that pseudo list item via JS since element styles can't be overwritten by CSS.
CSS Fix:
li {
transition: all 0.2s ease;
}
li:first-child {
transition: none !important;
}
This example is supposed to show a scroll which keeps its position after refresh.
It's simply not working : try a few refreshes. Both topVisble and offset values change.
Fyi, I need this kind of example to call get method on different events :
Manually scroll inside ui-scroll and keep its functionalities active
This issue is a duplicate one from old repo: Hill30/NGScroller#71.
Here is a useful topic on stackoverflow: http://stackoverflow.com/questions/19235832/outerheighttrue-does-not-include-margins.
The wiki doc for applyUpdates(index, newItems)
says that
index provides position of the item to be affected in the dataset (not in the buffer).
But I think its the other way around, the index here is the index of the item in the buffer and not the underlying dataset. I say this because $index is sometimes a negative value. Can you please clarify?
UI-Scroll seems not be able to handle "smooth scrolling" on iOS and OS X devices correctly. To reproduce use an iOS device or a OS X device controlled by the trackpad and apply -webkit-overflow-scrolling: touch
to the parent div of ui-scroll.
The scroller will load new content dynamically, but then once scrolling stops the scroller jumps to an incorrect position which can be quite confusing for the user (especially on small screens where you may not notice that you just jumped ~5 lines).
I'm attempting to get ui-scroll setup in my project that currently has paging, but it doesnt seem to be executing my get. We are using Typescript, so maybe I'm missing something in the conversion. If I set a breakpoint in the ui-scroll code, and check datasource in console, it does show my function in the object. But breakpoints inside my function and my loadOrgList function aren't touched. I tried to emulate the scopeDatasource example. Any suggestions are welcome!
Also, how is count calculated? Can I pass count a static number so it only loads 10 records at a time?
Thanks!
HTML template:
<div class="row searchResultsContainer" ng-hide="oc.orgList.results.length == 0" ui-scroll-viewport> <!-- Hide the Add block until functionality is ready --> <div class="col-sm-6 col-md-3 ng-hide"> <div class="orgAdd"> <span class="pc pc-add-call"></span> </div> </div> <div class="col-sm-6 col-md-3" ui-scroll="org in datasource"> <div class="orgCard" ui-sref="search.organizations.orgProfile({externalOrgId: org.id })"> <span class="orgName">{{ org.name }}</span><br /> <span class="orgType">{{ org.companyType }}</span> <div class="orgUpdated"> <hr /> <span>Last updated: {{ org.modifyDate | date:"MM/dd/yyyy" }}</span> </div> </div> </div> </div>
Controller:
`export class OrgController extends AbstractSearchController {
public orgList: PaginatedResults;
public itemsPromise: ng.IPromise;
public result: IOrg[];
/** @ngInject */
constructor(protected $rootScope: any,
protected $scope: any,
protected $state: any,
private orgService: IOrgDataService,
private contactsService: IContactsService) {
super($rootScope, $scope);
var that: OrgController = this;
var datasource: any = {};
this.$scope.datasource = datasource;
datasource.get = function(index: number, count: number, success: any): void {
const that: OrgController = this;
this.result = [];
that.itemsPromise = this.orgService.loadOrgList(this.$rootScope.search.text, index, count)
.then((paginatedResults: PaginatedResults<IOrg>) => {
for (var i = 0; i < paginatedResults.pageSize; i++) {
that.result.push(paginatedResults[i].data);
}
success(that.result);
});
};
...`
I have a angular-ui ui-scroll directive (1.3.0) living in a div that is hidden by default with an ng-show. When it is hidden, ui-scroll just keeps loading data from the datasource even though the ui-scroll-viewport's height is set. If the div is shown, it behaves correctly.
I'm sure I can solve this with an ng-if to dynamically add this to the DOM. However, I wanted the div to hide/show responsively - so driven off of css.
Any suggestions on how to have ui-scroll only load 1 page from the buffer when hidden? thank you.
http://stackoverflow.com/questions/31996151/prevent-angular-ui-ui-scroll-from-loading-in-hidden-div
I have to fetch the list results from App Engine so the get(index,count,success) method of fetching results will prove much more expensive than fetching results after the cursor retrieved during last list fetch. So working with a method like get(cursorString,nextOrPreviousItemsBoolean,count,success) will be very helpful. Is this something that we could see in an upcoming release?
I'm curious. It states:
uiScroll directive solves this problem by dynamically destroying elements as they become invisible and recreating them if they become visible again.
So it does not recycle the html elements? (illustrated in the gif below for clarification)
http://rad-js.com/wp-content/uploads/2014/02/list3.gif
My other question is when an element is removed, is the data from the element stored (so the application does not have to re-fetch the data), an example would be http://davidchin.me/blog/endless-scrolling-in-angularjs/ which does a shallow copy, truncates it, and uses ng-repeat directive to render the truncated collection.
Also may you put up at least one example without using coffee (I do not use coffee).
Also how does one install this module, there are no clear instructions.
How to turn off scroll up ???
is there an example for filtering the list? like a searchbox
Hi,
I am using the ui-scroll on a Table with a fixed header and Bootstrap table-stripped. The table header remains fixed and the main body scrolls ok, but.......
I'm getting an extra blank first row at the top of my html Table.
Any idea what I'm doing wrong?
Can you point me in the right direction of a Bootstrap fixed header scrolling table that uses the ui-scroll directive?
Any help appreciated.
Regards,
Paul
In issue#10 we have a link to some repro -- https://github.com/AlSherif/AngularUIScrollDemo -- and I researched a problem and found out that on a big list with different height items it is possible that the actual error of average items height calculation affects process of scrolling itself. It causes infinite scrollbar jumping in some cases, the repro demonstrates it well.
Padding elements adjustement (Viewport.adjustPadding()) may throw us in a backward direction while we are scrolling forward.
upd: Another one demo -- which is more easy to run -- that shows us the same problem: https://jsfiddle.net/MartyBolton/s38zdu8c/6/. This one cames from issue#65.
Hi, I know you talked about cursor based scrolling before and to some extent this is up to the datasource but I'm wondering... is there an easy way to figure out direction? This way, I know to use a cursor based feed like twitter's max_id and since_id or other cursor based ids to go off and fetch dynamic feed data based on a cursor. So, being new to ui-scroll can you point me to how I can get direction from the next datasource get event? Or have you considered adding this? Basically, I'm thinking I use the direction to know if I should get next set of results or previous. I guess I can use the topvisible and do math on the index or something, hoping you can show me valid syntax to calculate direction. What can I do in my get to calculate the direction you think?
thanks
Marty
The doc says
The value is relative to the visible height of the area, the default is 0.5 and the minimal value is 0.3
But according to the code both default and minimal values are 0.1
function bufferPadding() {
return viewport.outerHeight() * Math.max(0.1, +attrs.padding || 0.1);
}
I can fix the code to make it according to the doc.
Otherwise the doc should be fixed.
Is it possible for a controller to scroll to the index of a certain item in the list?
I've dug around but though to ask before building my own solution. Thanks!
I am using jquery-1.11.2 and not using ui-scroll-jqlite, the problem what i am facing while implementing ui-scroll is,
if i use ui-scroll-jqlite along with jquery means also the same error exists, i can't remove jquery in my project. Why this error is happening?
See to the plunker link for the further details,
http://embed.plnkr.co/TjlzuAg5Pbmf8WVdN27V/preview
why this error is happening with ui-scroll with jquery?
Hi, thank you very much for this directive.
I just found that when the ui-scroll-viewport
is hidden together with its children, and the only way to show is to click a button or whatsoever, the whole datasource
is retrieved and the infinite scroll will never work.
Here is what I'm talking about (to show my point I added the code to this working fiddle): just check the console.log
s.
Am I missing something from the docs or previous issues or have I just found a brand new bug?
Hello,
ui-scroll look great, thanks !
But I'm not yet very experienced with angularjs and I'm definitely not a coffee addict :-)
Using coffee 1.10.0, In the demo/examples directory I tried to get back to good old javascript with:
coffee -b -c *.coffee ../../src/*.coffee
sed -r -i -e s/\.coffee\"/\.js\"/ *.html
sed -r -i -e s/\\/coffeescript\"/\\/javascript\"/ *.html
sed -r -i -e /coffeescript.org/d *.html
But then something get wrong with angular initialization (no substitutions in the view, no messages in the console).
I need some help to solve this issue... (and a coffee right now)
Thanks !
When the height of the scroller item is the height of the image which is taken from the remote, an unpleasant thing can happen:
I installed the ui-scroll with the ui-utils.
Even with the simple provided examples i'm getting error : viewport.offset is not function.
I tried to install the ui-scroll directly and now getting the error element.before is not a function
I know the issue is related to the jqlite, but can't add it in my bower. (errors). Where to to load it?
any help would be appreciated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.