VirtualScroll update: Show spinner before and hide it when update completed


#1

Hi all,
I am using VirtualScroll with an array that is changed (basically sort key and sort order).
I want to display a spinner before manipulating the array and hide it when done.
Basically

.ts

    tmpArray = vsArray;
    document.getElementById("mySpinner").setAttribute('style', 'visibility:visible');
    vsArray = tmpArray.sort(...);
    document.getElementById("mySpinner").setAttribute('style', 'visibility:hidden');

.html

    <ion-list [virtualScroll]="vsArray">
        <button ion-item *virtualItem="let item" (click)="didSelectRow(item)">
            {{item}}
        </button>

The problem is that the spinner DOM updates happen is sequence and VirtualScroll update triggered by vsArray change happens asynchronously after this code sequence. I tried using DOMController.write instead of accessing DOM directly, but I have the same behaviour since the spinner DOM updates are queued before VirtualScroll DOM updates.

How can I make sure the spinner hides only after the VirtualScroll update is completed ???

Thanks
Martin


#2

Hi,

Instead of manipulating DOM programatically you could use binding:

<ion-spinner *ngIf=loading>

And in your ts file:

loading=true;

asyncTask.then(whatever => {
doSomething();
loading=false;
}

I am on Ipad so I cannot provide an exact sample

Hope it helps


#3

Thanks for your reply @pannemann that is exactly the big question…
Which asyncTask is triggered in VirtualScroll when it is starting to update following an array change???
Does it return a promise???
Can I provide a completion handler???
tx
mp


#4

Could you provide a piece of Code? Actually I don‘t know what you mean with ‚triggered by VritualScroll‘.
In my App VirtualScroll is bound to an Array. The Data changes just inside the array

So maybe something like Array.filter()

And in this function where the filtering is being performed you can set loading


#5

The code snippet is provided in my first post, there is not much more to it.
array.sort(…) runs in a few milliseconds, but when vsArray is modified, virtualScroll needs to re-render the array, so a ‘VirtualScroll-async-update’ is triggered to reflect the new data or the new order in this case of the array.
vsArray is the array used in html template virtualScroll like

        <ion-list [virtualScroll]="vsArray">
          <button ion-item *virtualItem="let item" (click)="didSelectRow(item)">
            {{item}}
          </button>

#6

@pannemann,
I tried your *ngIf approach but as expected the behaviour remains the same since ‘loading’ turns false before VirtualScroll update terminates and even before it starts.

Here is a live code that exhibits this particular behaviour.


On the first tab ‘vScr+Seg+Rng’, toggle between FirstName and LastName using the control segment, you will notice a few seconds delay before the DOM is refreshed. During that time, the spinner should run (just beneath the segment) but it doesn’t since loading=true/loading=false are done before virtualScroll updates start.

The whole idea of VirtualScroll is to be quick but it still is not instantaneous. It would be nice to have a hook after virtualScroll has finished processing the changes like:

loading=true;                                  //turn-on the spinner
tmpArray = vsArray;                            //prevent virtualScroll reset/trigger
tmpArray.sort(...);                            //prepare the array
virtualScrollUpdateArray('vsArray', tmpArray)  //update the array
    .then(()=>{                                //when all DOM updates completed
        loading=false;                         //turn-off the spinner
    });

#7

Sorry,

I now understand your problem better. But I think in VirtualScroll there is no event that would fit your needs.
Maybe you could write to ionic support directly if they know a solution for that specific requirement. Sorry