Skip to content

Scroller position to top after fetching new data and unexpected scroll on mobile #355

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

Open
arl-dev-ko opened this issue Apr 2, 2025 · 24 comments

Comments

@arl-dev-ko
Copy link

I want to implement ui-scroller with parent scroll to handle my cart in my app where the max number of elements is 1000 ,how can i implement pagination and to fix scroller scrolling to the first element, and in mobile the ui isn't optimized @dhilt

@arl-dev-ko
Copy link
Author

public datasource = new Datasource({
get: (index, count, success) => {
const data = [];
for (let i = index; i < index + count; i++) {
if (i < this.cartItems.length) {
data.push(this.cartItems[i]);
}
}
if (this.cartItems.length >= index + count) {

  }else{
    if(this.cartItems.length > 0){
      this.loadingItems = true;
  this.page.page++;
  this.getCartItems(false,false);
    }
    
  }
  success(data);
},
settings: {
  adapter : true,
  bufferSize: 15,
  minIndex: 0,
  startIndex: 0,
  windowViewport : true
},

});
my data source and also in the response of getCartItems() called this function this.datasource.adapter.reload();

@arl-dev-ko
Copy link
Author

html template

......

@muchbetterug
Copy link

Can you please provide a minimal example on https://stackblitz.com/edit/ngx-ui-scroll-3-angular-17 ?

Thank you

@arl-dev-ko
Copy link
Author

@muchbetterug
Copy link

Thank you! You dont need to reload inside datasource get. Also you dont need to create new items in datasource get. You just read from a datasource there.

Heres your example working with less code: https://stackblitz.com/edit/ngx-ui-scroll-3-angular-17-2fj141ke?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.module.ts,src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.css

@arl-dev-ko
Copy link
Author

Yes thanks
but in my code i have this logic i receive the first 20 elements when scroller reach end i want to add new items how to implement this thing @muchbetterug

@muchbetterug
Copy link

The datasource get only fetches data. You read from a source, till the source has no new data.

I think we have the xy-Problem here. Can you tell me, what you want to do in the bigger picture?

@arl-dev-ko
Copy link
Author

I want to show my items of the cart where i receive the cart items from the server i get the first 20 than when list gets to the end i want to data to fetched but i have some unexpected scrolls

@muchbetterug
Copy link

Thx! In the datasource get method you implement the simple data fetching logic.

something like this:

get: async (index, count, success) => { const data = await fetchDataFromServer(index, count); success(data); }

there you fetch count cart items from the server, beginning at index.

the server responds with the requested count items.

if there are no more cart items, or not enough to fill out count, the server responds with an empty array [] or fewer items then count. eg just 2 instead of 20 like: [{id: x},{id: y}]

the scroller is intelligent enough to register, there are no more items and stops.

let me know if it works for you

@muchbetterug
Copy link

what is the signature of your server data fetching code? can it use the parameters count and index, or does it need pagination like page 1,2,3?

@arl-dev-ko
Copy link
Author

i use pagination like 1,2,3,...

@arl-dev-ko
Copy link
Author

is the scroller height sensitive i have some unexpected scroll when the new items are changed in the dom

@arl-dev-ko
Copy link
Author

also i get an array of objects form the server dose this works in this case i can't change the logic on the server

@muchbetterug
Copy link

the scroller works really well with variable heights. this library is truly wonderful - only the beginning may be hard :o)

for pagination you can transform the count and index to pages, look at this example:

`get: async (index: number, limit: number) => {
const pageSize = 20;
const startIndex: number = Math.max(index, 0);
const endIndex: number = startIndex + limit - 1;

const startPage: number = Math.floor(startIndex / pageSize);
const endPage: number = Math.floor(endIndex / pageSize);

const start: number = startIndex - startPage * pageSize;
const end: number = start + endIndex - startIndex + 1;

const requests: Promise[] = [];

for (let i = startPage; i <= endPage; i++) {
requests.push(
SERVERREADFUNCTION(i).toPromise()
);
}

return Promise.all(requests).then((res: any) => {
const data = res
.reduce((acc: any, result: any) => [...acc, ...result], [])
.slice(start, end);

return data;

});
},`

@arl-dev-ko
Copy link
Author

there are some errors how should i modify it the call to server for items
getCartItems(onDeleteShare = false, reset : boolean = true) {

this.appService
  .getElement(`selling/data/data/Cart/Items`, this.page)
  .subscribe(
    (response) => {
      if (getSafe(() => response.content.length) > 0) {
        const cartItemsWithForm = this.handelCartItemsForms(response.content);
        this.checkValidSupport(cartItemsWithForm);
        // this.cartItems = this.cartItems.concat(cartItemsWithForm);
        cartItemsWithForm.forEach(item => this.cartItems.push(item));
        this.cartItems = setLastAndFirstElemetOfGroups(groupCartItemsByGroupId(this.cartItems), 'purchaseGroupId');
        this.checkOptionalTerms();
        this.appService.cartItemsEmitter.emit(this.cartItems)
        if (response.content.length < this.page.size) {
          this.loadedAllItems = true;
        }
  
        this.showScroller = true;
        
  
      } else {
        this.loadedAllItems = true;
        this.manageDisableCheckout();
        // this.datasource.adapter.reset();
      }
      if (onDeleteShare) {
        this.sharedService.refreshCartObserver.emit({
          cart: this.cart,
          items: response && response.content ? response.content : [],
        });
      }
      this.loadingItems = false;
      this.loadedItems = true;
    },
    (error) => {
      this.loadedItems = true;
      this.loadingItems = false;
      this.loadedAllItems = true;
      this.globalHandlerService.showError(error);
    }
  );

}

@arl-dev-ko
Copy link
Author

the items model
cartItems: CartItems[] = [];

@arl-dev-ko
Copy link
Author

arl-dev-ko commented Apr 3, 2025

Can you provide a full example?
Thanks

@muchbetterug
Copy link

it seems you're loading the data seperate, but you need to load the data in the datasource get function

@arl-dev-ko
Copy link
Author

the pagination is fine now but

https://github.com/user-attachments/assets/0e2a4cfe-896f-4f72-8bb9-e8b923a8f1ad
can you check this behaviour when i scroll and itmes are changed in the dom i have this unexpected scroll

@muchbetterug
Copy link

Jeah! Please show me your datasource code

@arl-dev-ko
Copy link
Author

public datasource = new Datasource({
get: (index, count, success) => {
const data = []
for (let i = index; i < index + count; i++) {
if (i < this.cartItems.length) {
data.push(this.cartItems[i]);
}
}
success(data);
},
settings: {
adapter: true,
bufferSize: 20,
minIndex: 0,
startIndex: 0,
windowViewport: true,
sizeStrategy : SizeStrategy.Average
},
});

iam getting all data at once and than passing to the scroller when scroller dose the job of replacing the items in the dom happens that thing

@arl-dev-ko
Copy link
Author

public datasource = new Datasource({
get: (index, count, success) => {
console.log(index,count);

  if (index + count >= this.cartItems.length -1  && !this.loadedAllItems) {
    this.page.page++;
    this.loadingItems = true;
    this.getCartItems(false, false);
    this.appService.cartItemsEmitter.subscribe(()=>{
        const data = [];
        for (let i = index; i < index + count; i++) {
          if (i < this.cartItems.length) {
            data.push(this.cartItems[i]);
          }
        }
        success(data);
    })
  }else{
    const data = [];
    for (let i = index; i < index + count; i++) {
      if (i < this.cartItems.length) {
        data.push(this.cartItems[i]);
      }
    }
    success(data);
  }
},
settings: {
  adapter: true,
  bufferSize: 20,
  minIndex: 0,
  startIndex: 0,
  windowViewport: true,
  sizeStrategy : SizeStrategy.Average
},

});

this is with pagination

@muchbetterug
Copy link

Can you isolate the scroller and test again?

I think you may have multiple elements with margin before oder after the scroller, so its jumping. also the elements inside the scroller should not have margins (use paddings instead)

@arl-dev-ko
Copy link
Author

okay i will let you know

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