stackfull / angular-virtual-scroll

Source for the sf.virtualScroll module for AngularJS
MIT License
262 stars 42 forks source link

Calculating item height #17

Open fidoboy opened 10 years ago

fidoboy commented 10 years ago

Hi, i'm trying to use this on my project but my list is populated with rows with a non fixed height, some items has images, other only text, etc and data is being retrieved from a remote server; because this angular-virtual-scroll fails to render my items and it applies the same height to all new rows. There is any way to solve this and wait until the item is loaded or populated with the remote data to calculate the height?

Right now, my first items are being displayed with no problems but when i scroll down after some point, all items begin to have the same height, and also when going back, scrolling upwards again, the items are being displayed with a fixed heigh also.

Thanks in advance,

stackfull commented 10 years ago

Unfortunately, there's no way to solve this - even in theory.

In order for any scroller to control the position of a list of elements, the total pixel height must be known. In non-virtual scrolling, this is simple as everything is rendered. In virtual scrolling, the only way is to either calculate the height (row height x number of rows) or render every element - in which case it's no longer virtual.

If you really need variable height, you'll have to use another technique. If the number of rows is manageable and the content is unchanging, try bindonce to prevent the watches building up. Otherwise, ngInfiniteScroll should be able to handle your case as it changes the scroller each time you hit the bottom.

Leaving the issue open to remind me to put this in the Readme - looks like I forgot.

fidoboy commented 10 years ago

well, just an idea, but, why don't you wait until the content is rendered and then calculate the height? also for already rendered items that are not visible on the viewport (because they are upwards) you can memoize each height and then apply it when the item becomes visible again...

stackfull commented 10 years ago

You'd have to render all the elements in order to get the full height to use for the scrollable area. You couldn't render the scroll bar until you had done that.

fidoboy commented 10 years ago

Yes, that's my idea, if you get height on DOM ready, then you can calculate the items height… isn't it?

stackfull commented 10 years ago

If the height of each element in the repeater is different, then you have to render every element in order to sum them up for the total height. If you were able to render them all, why would you need a virtual repeater?

fidoboy commented 10 years ago

because the items are being loaded dynamically. Just think in the Facebook stream in mobile app. Items are being loaded when you go down. My idea was that items outside the viewport are hidden to save resources and memory… but my be that this is not the right approach. What do you think?

stackfull commented 10 years ago

Maybe what you are describing is "infinite scrolling" rather than "virtual scrolling". Virtual scrolling looks exactly like the normal, static case; it just optimises away the non-visible elements. Infinite scrolling is a subtly different approach and it looks and feels different in use - the scrollbar bounces when you hit the bottom.

I suggest you check out http://binarymuse.github.io/ngInfiniteScroll/ It probably does exactly what you need.

jmaynier commented 9 years ago

Yes but ngInfiniteScroll does not do virtual scrolling, every time you reach the bottom the new nodes are created and the old ones remains even if not in the viewport. virtual scrolling and infinite scrolling are 2 orthogonal problems. You could have a need for both on the same list

decklord commented 8 years ago

Any ideas on this?

mikila85 commented 8 years ago

+1

lordmos commented 7 years ago

I have two "not good enough" idea .

  1. You can have a function like "getHeight()" . Once we get a data from web ,we can calculate the item one by one ,without render . Why without render ? We have a view pattern so we can calculate by "oh I got a title so height + 10 , oh a text ,+ 20 ,good an item's height is 30 " . Then you can get item's height by user ,and show 'dynamic' item height list.
  2. You render list items one by one and save the item's height in a list , then you can calculate height with a loop .

How about this two solutions ?

VladBrok37 commented 9 months ago

@stackfull If "it is not possible even in theory" then how does all apps such as Telegram or VK or Facebook work with infinite amounts of messages and posts, each one with different height? If I keep scrolling to bottom, scrolling and scrolling, at some point I will have 10000000 posts rendered and my phone will die, but id does not die, so I presume these apps use virtual scroll. @lordmos your solution (point 1) looks good