Ionic-framework: Conditional on VirtualScroll causes no content to be displayed in any case

Created on 15 Dec 2016  路  30Comments  路  Source: ionic-team/ionic-framework

Ionic version: (check one with "x")
[ ] 1.x
[X] 2.x

I'm submitting a ... (check one with "x")
[X] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/

Current behavior:
Conditional on VirtualScroll causes no content to be displayed, even if there should be content. This is on rc4.

Expected behavior:
If there's a conditional, it should still work if the condition returns true. It used to work like this on rc2.

Related code:
html:

    <ion-list [virtualScroll]="dataStorage" [headerFn]="headerFn" *ngIf="dataStorage">

        <ion-item-divider *virtualHeader="let header" class="dividers">
            {{ header }}
        </ion-item-divider>

        <button ion-item *virtualItem="let data" (click)="openData(data.id)">
            {{ data }}
        </button>
    </ion-list>

ts:

    headerFn(record,recordIndex,records){
        if( recordIndex == 0){
            return;
        }
        return null;
    }

Other information:
If I take the same code and take out the *ngIf="dataStorage", it displays correctly.

Ionic info: (run ionic info from a terminal/cmd prompt and paste output below):

Cordova CLI: 6.3.1
Ionic Framework Version: 2.0.0-rc.4
Ionic CLI Version: 2.1.17
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.47
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.7.0
Xcode version: Not installed
v3

Most helpful comment

@jgw96 - for a final release there are still some really big bugs with virtualscroll, could they please get some attention?

Working with conditionals / segments is a key one, otherwise use cases are really limited.

All 30 comments

Having a similar issue although it was working for me back as recent as rc.3.

Well, I skipped rc3, hence why I only now saw it.

VirtualScroll with InfiniteScroll is more unreliable in RC 4 than it was in RC 3. It sometimes display images and sometimes it doesn't. When InfiniteScroll loads the contents, VirtualScroll clears all contents from the screen, and just displays white area. If we try to touch and scroll white area (up or down) it triggers InfiniteScroll and send request to server to fetch next page's record..

This issue appears for me with [ngSwitch], as well. My quick fix has been to convert those views to nested tabs, since the content isn't conditional at that point. This isn't really a solution, as the <ion-segment> is a very useful component for displaying multiple lists in a single view container.

I'm having the same issue.
Event surrounding the virtualScroll list in another div where I set the condition on doesn't fix the problem (yes, the condition is correct ;-))

virtualScroll does not work in segments in RC5. As stated above [ngSwitch] is used as a conditional to change the content for the different segments. The first shown segment when entering a page will display correctly, as soon as you navigate to another segment it's just a white page with no content shown.

7734 - is related to this issue. I have done a little troubleshooting and found something that might help the team to fix this:

attached are 2 screenshots, the first working.png is when I first enter a page that has a virtualscroll list inside a segment. On that first load the segment shows the content correctly.

the second second screenshot shows when I navigate to a different segment and then come back to the original one. It is now showing a blank white page instead of the list. I can see that all of the list items are present in the DOM.

There is a clear issue with the CSS though:
working list has .ion-list.list.list-ios.virtual-scroll with a height value as it's first property
blank list has .ion-list.list.list-ios.virtual-loading with no height

working list has .virtual-scroll class with position: relative
blank list has .virtual-loading class with opacity: 0 and no position value.

seems like when there is a conditional virtual-scroll gets stuck in it's loading state and never transitions to being visible.

working
blank

seems that when a conditional is in use this._init is not set so ngDoCheck() doesn't run and hence the virtualScroll list gets stuck in loading state.

If I edit the virtualScroll component and just remove this._init from the if statement in ngDoCheck() then the virtualScroll list is properly rendered when inside a conditional, although it does "pop" in as a result of this change.

ngDoCheck() {
if (this._init && this._hasChanges()) {
// only continue if we've already initialized
// and if there actually are changes
this.readUpdate();
this.writeUpdate();
}
}

I'm upgrading from rc.3 with a similar template as yours and it seems like this is still an issue in 2.0.0 final after playing around with it.

This is indeed still an issue for me in 2.0.0 final virtualscroll does not work inside ngSwitchCase

@jgw96 - for a final release there are still some really big bugs with virtualscroll, could they please get some attention?

Working with conditionals / segments is a key one, otherwise use cases are really limited.

This is still an issue more than 6 months after the bug was first raised.

@manucorporat:
I still have this issue in Ionic 3.9.2.

The problem seems to be that VirtualScroll isn't initialized because it listens to readReady/writeReady (ViewController), which only fires once(?) on page transition.

https://plnkr.co/edit/almnrjeRzA2zWq0S3KYj?p=preview

I still have this issue with 3.9.2. I cannot toggle between two virtualScroll lists that are built from the same array that are inside *ngIf

I opened a PR https://github.com/ionic-team/ionic/pull/13406 which should fix the problem here. Please try it and tell me if it's working :)

Is there a status update on this please?

@ryanhalley I made a PR #13406 but it's not merged yet. You can build ionic-angular by your own if you want, or download my build on my PR and replace it in your node_modules folder.

I made an update of my build as there was an unhandled edge case when VS is recreated after being destroyed... You can find it here: #13406

fixed:
@ViewChild('virtualScroll', { read: VirtualScroll }) virtualScroll: VirtualScroll;

setTimeout(() => {
this.virtualScroll['_ctrl'].readReady.emit();
setTimeout(() => this.virtualScroll['_ctrl'].writeReady.emit(), 300);
}, 300)

to get around this I change around the virtualScroll's inputted array values

ex.
[virtualScroll]="searchValue !== '' ? list : []"

@442623641 Nice one! I just put this into a "refreshVirtualScroll" function and call it when the conditional changes and all behaves more like it should. I dropped the timeout values down to 100 as well and still all looks good with a much less noticeable delay.

Hopefully this is no longer needed when ionic v4 arrives or the PR above gets merged for V3 so this isn't even needed any more.

For now though I can finally use virtualscroll inside a conditional.

A quick fix for now -

@ViewChild(VirtualScroll) virtualScroll: VirtualScroll;
virtualScrollHack() {
this.cdRef.detectChanges();
this.virtualScroll['_ctrl'].readReady.emit();
this.virtualScroll['_ctrl'].writeReady.emit();
}

Can confirm that this bug still exists on Ionic Framework Version 3.9.2. Sadly, PR #13406 wasn't merged into master, because of significant master changes introduced by the porting of all of the Ionic components to web components...

@HugoHeneault
Could you refactor your solution and submit a new PR? pretty please O:-)

@benjhess My PR should work on 3.9.2, and it won't be merged through the 3.9 base. There are some quick fix working well without having to rebuild ionic. I haven't checked the new v4 virtualscroll yet...

A quick fix for now -

@ViewChild(VirtualScroll) virtualScroll: VirtualScroll;
virtualScrollHack() {
this.cdRef.detectChanges();
this.virtualScroll['_ctrl'].readReady.emit();
this.virtualScroll['_ctrl'].writeReady.emit();
}

What is this "this.cdRef" ??

Change detection reference

cdRef is ChangeDetectorRef

This issue has been automatically identified as an Ionic 3 issue. We recently moved Ionic 3 to its own repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.

If I've made a mistake, and if this issue is still relevant to Ionic 4, please let the Ionic Framework team know!

Thank you for using Ionic!

Was this page helpful?
0 / 5 - 0 ratings