naver / egjs-infinitegrid

A module used to arrange card elements including content infinitely on a grid layout.
https://naver.github.io/egjs-infinitegrid/
MIT License
2.22k stars 95 forks source link

When the page scrolls to the bottom, the list data keeps loading infinitely #508

Open WilliamFocus opened 2 years ago

WilliamFocus commented 2 years ago

Description

When the page scrolls to the bottom, the list data keeps loading infinitely, So I hope the data should stop loading when MasonryInfiniteGrid is not visible in the page, how should handle this? thanks.

Steps to check or reproduce

https://codesandbox.io/s/black-glade-oednu3

daybrush commented 2 years ago

@WilliamFocus

Change the state when last.

const [items, setItems] = React.useState(() => getItems(0, 10));
  const [last, setLast] = React.useState(false);
  return (
    <MasonryInfiniteGrid
      className="container"
      gap={5}
      align={"justify"}
      onRequestAppend={(e) => {
        const nextGroupKey = (+e.groupKey! || 0) + 1;

        if (last) {
          return;
        }
        if (nextGroupKey >= 10) {
          setLast(true);
        }
        setItems([...items, ...getItems(nextGroupKey, 10)]);
      }}
      onRenderComplete={(e) => {
        console.log(e);
      }}
    >
...
</MasonryInfiniteGrid>
JohnRSim commented 1 year ago

@daybrush I'm getting the same issue with svelte.

If I move the scrollbar to the bottom of the page - then there is an infinite load with the scroll staying fixed at the bottom whilst the loaded data is being added correctly and paged but the scroll bar does not bounce up to the footer of the previous group to allow me to scroll down and see the new data loaded.

As the scrollbar appears fixed to the bottom showing loading message it keeps triggering the requestAppend which is correctly loading and paginating the data.

<MasonryInfiniteGrid
    useLoading={true}
    class="container"
    gap={20}
    items={items}
    align="center"
    on:requestAppend={async ({ detail: e }) => {
        e.wait();
        console.log('[requestAppend]');
        const nextGroupKey = (+e.groupKey || 0) + 1;
        const response = await fetch(`/api/requests/getMediaTimeline`, {
            method: 'POST',
            body: JSON.stringify({
                key: 'val',
            }),
        });
        let res = await response.json();

        //setTimeout(() => {
            e.ready();

            items = [
                ...items,
                ...getItems(nextGroupKey, res.tweets.length),
            ];
        //},1000);
    }}
    let:visibleItems
>

    {#each visibleItems as item (item.key)}
    {#if item.type === ITEM_TYPE.NORMAL}
            //gen gallery item
    {:else if item.type === ITEM_TYPE.LOADING}
        <div class="loading">Loading...</div>
    {/if}
zozero commented 1 year ago

@JohnRSim @WilliamFocus 我使用的是angular 我找到了一个解决方法,我的情况是在使用dexie数据库时需要异步获取数据,这意味着我不能在infinitely组件加载完毕前获取数据,而且之后的数据加载则会导致排版出现问题。 我发现当没有数据时onRequestAppend这个事件会同时调用两次,这意味着你的数据会直接重叠,非常令人痛苦。 以下是我的解决方法:

 status: boolean = false;
 count: number = 0;
 //在构造函数中执行,因为它是最先执行的函数
 constructor() {
    //我先用dexie数据库查了一下多少条数据,并且我通过这个方法成功的将异步变成了同步
    historyDB.historyTable.count(async count => {
      console.log("count", count)
      //用来计算我数据库中数据有多少条,防止无限获取数据
      this.count=count;
      // 在这里第一次获取数据
      this.items = await this.getItems(0)
     //这是我用来防止onRequestAppend多次调用改变数据的,当变成true的时候我在让他去获取并改变数据
      this.status = true
    })
 }

 // 请求新的数据,它会自动调用,
  async onRequestAppend(e: OnRequestAppend) {
   //groupKey这是一个十分关键的变量,它的变化贯通了整个数据,但我已经避免它影响数据的更新操作
    const nextGroupKey = (+e.groupKey! || 0) + 1;

    if (this.count <= this.items.length || !this.status) {
      return;
    }
    else {
      console.log("onRequestAppend")
     // 在这里获取数据
      let datas = await this.getItems(nextGroupKey)
     //防止空数据也更新
      if (datas.length > 0) {
        this.items = [
          ...this.items,
          ...datas
        ];
        console.log("this.items count", this.items.length)
      }

    }
  }