I don't know why the virtual scrolling I implemented is looking weird.
I have a list of words and I wanna show them in a page. earlier I iterated these words using a for loop but the scrolling performance was horrible in android devices. So I decided to implement basic virtual scrolling as mentioned in ionic's official documentation.
http://rhymebrain.com/talk?function=getRhymes&word=baby
This is the data That I'm trying to iterate. I only need the words, no other info.
Code for my virtual scroll looks like this:
<ion-card *ngIf="words?.length > 0">
<ion-card-header>rhymes with...</ion-card-header>
<ion-card-content>
<ion-list [virtualScroll]="words" [approxItemHeight]=" '500px' ">
<button *virtualItem="let word" ion-button round small>
{{word.word}}
</button>
</ion-list>
</ion-card-content>
</ion-card>
In my web browser, the results I got are terrible. I will share some screens:
Pic 1: User searches for a word to fetch all rhymes but no data is shown even when response is not null.
Pic 2: If I navigate to another page and come back, I see a few of the rhymes.
Pic 3: If I repeat step 2 or scroll a little down, I see few more words. It looks so weird.
I have no idea why virtual scroll is acting like this. Can anyone tell me what mistake I made or a better solution for this?
thanks in advance
There's a few issues with virtual scroll that are unfortunately not documented. Fixing all these should get you in the right direction.
Predefined Height
All ancestors of your [virtualScroll]
must have a predefined height. The virtual list will grab the elements height and based on that, populate the cells. If the height is 0, it will populate only a few cells which make up for the buffer space of scrolling quickly. Don't use inline CSS but for simplicity here's an example.
<ion-content>
<div style="height:100%">
<ion-list [virtualScroll]="items" approxItemHeight="50px">
...
</ion-list>
</div>
</ion-content>
Define Approximate Item Height
In the example above you can see I'm setting approxItemHeight
. This is an important step that helps the virtual list with it's calculations.
Don't Wrap In If Statement
Unfortunately you can't put your virtual scroll inside an ngIf
, ticket. Your virtual scroll needs to be rendered at the beginning of your components life cycle. So if you wrapped your virtual scroll inside of a condition which from the time of the constructor was equal to true, the issue would not exist. However if some point later on the condition becomes true, you'll have to redesign your implementation.
What I did for this was switch from using *ngIf
to using [ngClass]="virtualClass"
. When I want to hide the virtual scroll I will set virtualClass = 'virtual-hide'
.
.virtual-hide {
overflow: hidden;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
You can't use display: none
since this will not render the virtual scrolls height, same problem we want to resolve. The above CSS should allow for the element to be on screen and take up the correct amount of space while not appearing to actually be there. This code might need to be adjusted based on your implementation.
Ensure Items Exist
Switching to using ngClass
from ngIf
will mean your virtual scroll is always in the DOM. Because of this, you must make sure that items
(the array for [virtualScroll]
) is always set. So make sure it's never undefined
or null
, instead set it to []
if you want it to be empty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With