Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to implement nested uiScroll? #346

Open
tradingproject19 opened this issue Nov 9, 2023 · 4 comments
Open

Is it possible to implement nested uiScroll? #346

tradingproject19 opened this issue Nov 9, 2023 · 4 comments

Comments

@tradingproject19
Copy link

Hello,

First of all thank you for this awesome library, we have migrated our source from angular virtual scroller to this library.

Everything seems to be working fine, we have one page where we have nested data,

Following is the structure of our data source.

public rooms: Array<{ name: string; isChecked: boolean, defs: WalkthroughDeficiency[] }> = [];

following is the html template:

<div [style.height.px]="contentHeight" style="overflow-y:auto">
    <div *uiScroll="let room of datasource">
      <ion-list-header *ngIf="room" color="secondary" class="ion-no-margin ion-no-padding">
        <ion-label class="ion-no-margin ion-margin-vertical ion-text-center">{{room.name}}</ion-label>
      </ion-list-header>
      <ion-item *ngFor="let def of room.defs" class="ion-no-padding ion-no-margin no-padding" lines="none">
        <ion-label class="ion-no-margin ion-margin-vertical ion-text-center">{{def.room}}</ion-label>
      </ion-item>
    </div>
  </div>

and following is the code for intializing the data source.

ngOnInit() {
this.datasource = new Datasource({
      get: (index, count, success) => {
        const data = [];
        const start = Math.max(0, index); // or 0
        const end = index + count - 1;
        if (start <= end) {
          for (let i = start; i <= end; i++) {
            if (!this.helper.isNullOrUndefined(this.rooms[i]))
              data.push(this.rooms[i]);
          }
        }
        success(data);
      },
      settings: {
        minIndex: 0,
        startIndex: 0,
        bufferSize: 5,

      },
      devSettings: {
        debug: true,
        immediateLog: true,
      }
    });
}

Is there a way to use uiScroll with room.defs, or can I extend the datasource and create my own datasource, passing the roomCode so that its get method can receive the roomCode and filter based on the roomCode as well?

Thank you.

@tradingproject19
Copy link
Author

Okay so I have changed the data structure and removed nested data.

Now there's an other problem sometimes it shows empty white space on top:

image

@dhilt
Copy link
Owner

dhilt commented Nov 9, 2023

@tradingproject19 White space seems to be an issue. I would gladly look at the code if you could provide a repro on stackblitz (fork this one or make your own from scratch).

@tradingproject19
Copy link
Author

@dhilt thanks for prompt response.

Here's the demo link which has problem:

https://stackblitz.com/edit/ionic7-label-test-gpznh5?file=src%2Fapp%2Fapp.component.html

image

@dhilt
Copy link
Owner

dhilt commented Nov 12, 2023

@tradingproject19 Thanks for the repro, I have reproduced the issue, and this is very interesting problem. The following piece of the App log is responsible for the issue:

error: Can't set buffer items (loop 1-259-360)

This is a critical error, meaning the Scroller got broken. Looks like it relates to how the ionic framework renders their components. They use Shadow DOM and perhaps not a very straightforward rendering mechanism, and, I guess, sometimes the App falls into a kind of race conditions, because the Scroller deals with only real DOM in a very blunt way. Specifically, the ionic components rendering may take more time than 1 browser reflow cycle (which is the expecting by the Scroller), so the Scroller may get 0 as a new row height value. It's a pretty vague suggestion, but adding a plain DOM fragment with a row template height constraint fixes half the problem.

<div *uiScroll="let def of datasource">
  <div style="min-height: 1px">
    <ion-list-header> ... </ion-list-header>
    <ion-item> ... </ion-item>
  </div>
</div>

Now the Scroller doesn't get broken. It continues working and provides consistent scroll position even if the ionic components render with delay. The next problem is that the height of the entire viewport might jump, which also affects the user experience. This issue is less critical, let me not describe it, you may try it yourself. To improve situation you may set "min-height" to a real minimum height value (instead of 1px). Anyway, this is not a solution, but a sort of workaround. Let me think what else can be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants