orizens / ngx-infinite-scroll

Infinite Scroll Directive for Angular
https://www.npmjs.com/package/ngx-infinite-scroll
MIT License
1.23k stars 223 forks source link

Initiate call when initial load does not fill screen #207

Closed nerijusgood closed 2 months ago

nerijusgood commented 6 years ago

Hi,

I am not sure if this is a feature of this tool, but I would like to call when the data does not fill the screen, thus making screen not scrollable.

In my case I have dynamic amount of data and 8 out of 10 times its not enough to overflow and have scroll; Is there a way on initial load to trigger scroll is not there?

orizens commented 6 years ago

hi @nerijusgood try using [immediateCheck]="true"

nerijusgood commented 6 years ago

Well, nothing happens.

<div infiniteScroll [fromRoot]=true infiniteScrollContainer="main" [infiniteScrollDistance]="1" [infiniteScrollThrottle]="800" [infiniteScrollDisabled]="!noData" [immediateCheck]="true" [scrollWindow]="true" (scrolled)="onScroll()">

Where main is pretty much full screen.

adrienverge commented 6 years ago

I experience the same problem. It can be reproduced easily by using the demo plunker and replacing sum = 100 by sum = 10.

@orizens Unfortunately using [immediateCheck]="true" does not work, because the problem is an unsufficient first batch of items displayed (not enough data to make scrollbars appear). In @nerijusgood use case (and mine too), the addData() function returns a dynamic number of items (for me between 1 and 50), so when its below 10 it's not enough to fill the page. Still, we'd want to display this first 10 elements while fetching more items.

Should ngx-infinite-scroll keep calling addData() until the page is filled and scrollbars actually appear? (maybe with a switch to enable/disable this option)

Other than that, nice, easy-to-use and well-documented lib :+1:

nerijusgood commented 6 years ago

I would expect [immediateCheck]="true" to keep calling addData() until scrollbar appears, was that intended behavior or should I look for other ways to load until scrollbar appears?

adrienverge commented 6 years ago

From the documentation I would not expect that... I would expect addData() to be called once, in case the window already has scrollbars and a ngx-infinite-scroll code is loaded after the page has been scrolled:

immediateCheck - (optional, default: false) - invokes the handler immediately to check if a scroll event has been already triggred when the page has been loaded (i.e. - when you refresh a page that has been scrolled).

Let's see what the author has to say about that ;-)

orizens commented 6 years ago

@nerijusgood the original design (from v1 docs) would invoke the scroll handler once the element has load.

orizens commented 6 years ago

@adrienverge it sounds like what you describe there is logics that should not be part of this directive (imho). if you know up front that 10 is not enough, than hand over more than items to the element from start.

adrienverge commented 6 years ago

@orizens Thanks for this quick answer.

I don't know from start that 10 will be enough / not enough. It depends:

orizens commented 6 years ago

i can suggest that you'll apply a logic which adds checks if scrollbar is present- and then add items until it does:
you can apply this logics a directive - https://stackoverflow.com/questions/681087/how-can-i-detect-a-scrollbar-presence-using-javascript-in-html-iframe

adrienverge commented 6 years ago

Nice, it should do the trick!

What would be even nicer is to have it automatically done in ngx-infinite-scroll, with an option like this:

<div class="search-results"
     infiniteScroll
     (scrolled)="onScroll()"
     [callbackUntilScrollable]="true">
</div>

Anyway thanks for your answer!

orizens commented 6 years ago

Nice. I'll think of how to integrate this.

On Sun, Dec 24, 2017, 16:57 Adrien Vergé notifications@github.com wrote:

Nice, it should do the trick!

What would be even nicer is to have it automatically done in ngx-infinite-scroll, with an option like this:

<div class="search-results" infiniteScroll (scrolled)="onScroll()" [callbackUntilScrollable]="true">

Anyway thanks for your answer!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/orizens/ngx-infinite-scroll/issues/207#issuecomment-353788596, or mute the thread https://github.com/notifications/unsubscribe-auth/AA1oROU19WULtrdjt1JuTKRb8dMbzA78ks5tDmY-gaJpZM4QddQF .

--

Oren Farhi Founder at Orizens.com Senior Front End Engineer & Consultant http://www.orizens.com

ghost commented 6 years ago

I use it for a gallery, if the user uploads 100 small images it wont work or when the user has a extremely high resolution.

Two cases where this loader won't work at all (BUG):

Another solution would be an optional 1x1 pixel sentinel element at the end of the collection or add elements until the scrollbar is visible. The bad thing about the sentinel is that it needs to recalculate the DOM to detect if it's on screen so a solution with checking the scrollbar is better.

rex-ya commented 6 years ago

I was inspired by the above and created the solution. @orizens However, I hope that these features will be done automatically as mentioned above. like [callbackUntilScrollable]="true".

Below is the code for Component using ngx-infinite-scroll.

=============================================== html:

<div #infiniteScrollParentElem
     infiniteScroll
     [scrollWindow]="false"
     (scrolled)="onScrolled();">
  <ul #infiniteScrollChildElem>
    <li *ngFor="let item of arr;">
        {{ item.value }}
    </li>
  </ul>
</div>

=============================================== typescript (Component):

@ViewChild('infiniteScrollParentElem') public infiniteScrollParentElem: ElementRef;
@ViewChild('infiniteScrollChildElem') public infiniteScrollChildElem: ElementRef;
public arr = [];

public ngOnInit(): void {
    this.getData();
}

public onScrolled() {
    this.getData();
}

private getData() {
    this.arr.push(< DATAS_FROM_SERVER >);
    if (<IS_MORE_SERVER_DATA>) {
        this.callbackUntilScrollable();
    }
}

private callbackUntilScrollable() {
    window.setTimeout(() => {
        if (this.infiniteScrollParentElem.nativeElement.clientHeight > this.infiniteScrollChildElem.nativeElement.scrollHeight) {
            this.onScrolled();
        }
    }, 500);  // If you use loading-placeholder.
}

I hope to help someone.

davefmoore commented 6 years ago

@orizens I am facing this same issue as the [immediateCheck]="true" seems to only emit on a scroll event... but there is not a scrollbar, so this event never can happen. In the https://stackblitz.com/edit/ngx-infinite-scroll demo, you can see the issue by changing the sum from 100 to 10.

In theory, I could get around this by loading more items... but the issue is I am loading a image grid (google photo like) where the content is horizontal, not vertical. In https://sroze.github.io/ngInfiniteScroll/ , the infinite-scroll-immediate-check A boolean expression that indicates that the directive should check immediately to see if a scroll event would trigger an evaluation of the infinite scroll expression even if a scroll event does not occur.

Also, another request is to have it re-check on window resize which is a must have in the responsive world. A good example of this is here https://github.com/metafizzy/infinite-scroll/blob/master/js/scroll-watch.js#L40.

If you can implement:

  1. scroll-immediate-check even if scroll event doesn't fire
  2. Window resize recheck

This would be the de-facto infinite scroll module for Angular 5/6+++

feitzi commented 4 years ago

Is there any news on this subject? We have the same problem if the user has a high resolution at the first load (Initial Load 100 entries), so no scrollbar is displayed. Therefore, the user cannot scroll down and cannot load more data. Therefore I need a notification that more data should be loaded even if the user does not scroll.

irinelpascu commented 4 years ago

I created a new directive for this which expects the number of items that are currently loaded. It will emit loadMoreItems only if we already have some items and no scroll

import {
  Directive,
  ElementRef,
  EventEmitter,
  Input,
  OnChanges,
  Output
} from '@angular/core';

@Directive({
  selector: '[insufficientItems]',
  exportAs: 'insufficientItems'
})
export class InsufficientItemsDirective implements OnChanges {
  @Input() existingItems: number;
  @Output() loadMoreItems: EventEmitter<void> = new EventEmitter();

  previousExistingItems: number;

  constructor(private element: ElementRef) {
  }

  ngOnChanges(): void {
    const htmlElement = this.element.nativeElement as HTMLElement;
    if (this.existingItems && this.existingItems !== this.previousExistingItems && htmlElement.clientHeight === htmlElement.scrollHeight) {
      this.previousExistingItems = this.existingItems;
      this.loadMoreItems.emit();
    }
  }
}

and use it like this:

<div class="conditions-list-content"
  infiniteScroll
  insufficientItems
  [existingItems]="(items$ | async).length"
  (loadMoreItems)="loadMoreResults$.next()"
  [infiniteScrollThrottle]="50"
  [scrollWindow]="false"
  (scrolled)="loadMoreResults$.next()">
mirisbowring commented 4 years ago

Nice. I'll think of how to integrate this. On Sun, Dec 24, 2017, 16:57 Adrien Vergé @.**> wrote: Nice, it should do the trick! What would be even nicer is to have it automatically done in ngx-infinite-scroll, with an option like this: <div class="search-results" infiniteScroll (scrolled)="onScroll()" [callbackUntilScrollable]="true">

Anyway thanks for your answer! — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#207 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/AA1oROU19WULtrdjt1JuTKRb8dMbzA78ks5tDmY-gaJpZM4QddQF . -- Oren Farhi* Founder at Orizens.com Senior Front End Engineer & Consultant http://www.orizens.com

Any Progress on this?

JWess commented 2 years ago

I just read a blog post by someone who wrote a directive to do this exact thing. I haven't yet attempted to use this directive, but it sure seems like it would be a great addition to this project.

https://blog.kevynjaremko.com/2020/06/23/angular-triggering-infinite-scroll-without-enough-content-to-cause-overflow

JWess commented 2 years ago

I just read a blog post by someone who wrote a directive to do this exact thing. I haven't yet attempted to use this directive, but it sure seems like it would be a great addition to this project.

https://blog.kevynjaremko.com/2020/06/23/angular-triggering-infinite-scroll-without-enough-content-to-cause-overflow

I just modified this repo's demo Stackblitz to use the directive above, which solves this ticket's issue.

https://stackblitz.com/edit/ngx-infinite-scroll-bacfgf?devToolsHeight=33&file=src/app/infinite-scroll-trigger.directive.ts

sagrawal31 commented 1 year ago

Looking forward to having inbuilt support!