ajax 取資料分批加載更多按鈕

Chienwei
  • 135

小弟用ajax异步GET资料

遇到了一个问题,目前需求是要做加载更多的按钮

总共30笔资料来说

v-for先在页内渲染6笔资料, 之后按下依次按钮, 资料都多6笔, 直到30笔都载入完

现在有想法是

  1. 一次只抓6笔资料, 随后每次抓接下来6笔 concat到 数组, v-for的资料有异动应该会自动渲染新的UI
    ---> GET只能一次GET全部资料(?) 目前正在找这个方法, 不知道有没有一次只GET部分资料的方法, 有想过用length限制, 但看网上效能也会受到影响
  2. 先抓好30笔资料, 再用slice方法切割5个部分载入
    ---> 不知道效能会不会很差

想请问各位大神对这种状况有没有什么效能较好的思路?或是一次get部分资料的方法

回复
阅读 2.6k
5 个回答
✓ 已被采纳

从你的问题描述中,我认为这个问题的难点在于前端希望 6 个/页,而后端 API 给出的是 30 个/页,所以前端的页面加载动作并不是每一次都对应着 Ajax 操作。

解决这种问题可以采用 Facade 模式(也可能是 Adapter 模式,我不太会区分这些模式的名称,都了解下吧),目的就是写一个前端服务类,它对前端提供 6个/页的分页数据服务,并根据需要,适当的从后端 Ajax 获取数据。所以这个类内部会有一个数据缓存,用于存储从后端获取的数据。根据情况,可以考虑缓存所有数据(不仅 30 条),或者仅最后一次获取的数据(最多 30 条),或者前端当前页面附近的数据(比如 60 条)。

由于后端 Ajax 是异步接口,为了统一对前端的服务,这个服务类对前端提花 6 个/页数据的接口也采用异步方式,比如 Promise,或者回调。

假设这个类叫 DataProvider,提供了一个 .getPage(page: number): Promise(这是 TS 的类型声明语法,这里仅用于描述方法接口,非正确的 ES 语法) 用于对客户端提供 6 个/页数据,那么这个 .getPage() 方法的执行步骤大概是:

  1. 检查缓存中是否有需要的数据

    • 如果有,直接返回 Promise 封装的 6 个数据
    • 如果没有,执行 2
  2. 计算正确的后端页码,Ajax 从后端获取数据,然后

    • 将缓存加入缓存
    • 截取合适的 6 条数据返回

下面是用 TypeScriptasync/await 语法示例的伪代码

interface IModel {
    // ....
}

class DataProvider {
    cache;

    async getPage(page: number): Promise<IModel[]> {
        const pageData = this.getPageFromCache(page);
        if (pageData) {
            return pageData;
        }

        return this.getRemotePage(page);
    }

    private async getRemotePage(page: number): Promise<IModel[]> {
        // 简单演示从前端分页页码转换为后端分页的页码
        const remotePage = Math.floor(page / 6);
        // 简单演示从后端获取数据
        const data = await $.getJSON("....", { page: remotePage });

        // 这里把 data 缓存到 this.cache 中
        // 然后可以按原来的逻辑从缓存中获取当页数据
        // 如果仍然没有取到数据(服务端也没有),返回空数组 []
        return await this.getPageFromCache(page) || [];
    }

    private getPageFromCache(page: number): IModel[] | null {
        // 从 this.cache 中检查是否存在需要的数据
        // 如果存在返回 6 个
        // 否则返回 null
        return null;
    }
}

先要确认你的后端接口是否可以一次get一定数量的数据,就和分页一模一样。

如果可以,你每次传一个类似pageSize=6的参数,表示一次请求6个数据,传一个类似pageIndex=2, 表示请求第二页的数据(具体到你的需求,第一页就是最初的6个数据,pageIndex=1, 每点一下按钮pageIndex + 1)
如果不可以,就直接拿30个数据,每次push进去6个就可以了。

单就这个案例而言我建议你直接拿30条数据,毕竟数据量也不大,不存在太多性能问题;
如果对性能要求较高,或者考虑到以后也许有更多数量(200条数据)的类似需求,就按分页的思路来处理,毕竟稍微大些的项目里面,分页是必备的功能。

思路根分页毫无区别,前端返回一个页数给后端即可,每次拿到数据循环push进去

首先这个问题的本质就是分页问题。实现的基本思路也就是你说的这两种,其中第二种我是不建议的,通用性太差,只适合数据量少的时候使用。关于GET只能一次GET全部资料但不能GET部分资料这个问题,其实只要后台做一下控制就好了。你传一个类似pageNo这个参数来告诉后台你所需要哪6个资料就可以了。不过呢,如果你的后台是没法修改的话,那只好自己全部拉下来,然后自己用slice去切割了。

1.后台控制分页
2.接口不改的话那只能一次获取全部数据,自己切割了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏