资讯专栏INFORMATION COLUMN

miniui datagrid 的客户端分页解决方案 - CS结合

shixinzhang / 3103人阅读

摘要:在前一篇,的客户端分页解决方案中留下了一个问题如果前三页只需要加载一次数据,采用客户端分页,之后的每一页都仍然从服务器获取,应该怎么办现在就来改造,让它实现这个功能。所以正确的解决办法是试验一下就能证明它的正确性。

在前一篇,miniui datagrid 的客户端分页解决方案 中留下了一个问题:如果前三页只需要加载一次数据,采用客户端分页,之后的每一页都仍然从服务器获取,应该怎么办?

现在就来改造 ClientPagination,让它实现这个功能。不过在此之前需要先解决上个版本中存在的一个问题:destroy() 并没有完全恢复原有的 datagrid 对象,因为忘了在 destroy() 中恢复 this._datagridloadsetData 函数。

修复一个重要的 BUG

很容易想到下面的代码,不过下面这个代码是个错误的实现

    destroy() {
        // 错误的实现
        METHODS.forEach(name => {
            this._datagrid[name] = this._origin[name];
        });
        
        // ....
    }

别忘了 this._origin 中保存的每个函数都是通过原函数 bind() 而来,所以其实已经不是原函数了。此外,也很容易想到 miniui 的 datagrid 多半是类实现,原来的 load()setData() 应该来源于原型。所以正确的解决办法是

        // in destroy"s body
        METHODS.forEach(name => {
            delete this._datagrid[name];
        });

试验一下就能证明它的正确性。

改造 ClientPagination 修改 beforeload 事件处理

原来在 beforeload 事件中直接设置了 event.cancel = true 来避免远程加载,但现在情况发生了变化,只需要在页码小于3(miniui 的 pageIndex 是从 0 开始)避免远程加载,大于等于 3 的时候仍然需要从服务器获取页面数据,所以

const pageIndex = e.data.pageIndex;
if (pageIndex < 3) {
    e.cancel = true;
} else {
    // 直接返回,不需要通过 setPageData() 来设置页面数据
    return;
}
接下来该干啥

接下来还有一些细节需要处理。

首先就是 setData 中没有使用数据的 total 值,因为原来纯客户端分页的时候,数据总行数就是 total 值,但现在不一样了,设置的数据不一定是所有数据,所以需要先检查 total,如果没有 total 再使用 rows.length 代替。

setData(data) {
    const rows = Array.isArray(data)
        ? data
        : (data.data || []);

    this._data = rows;
    this._total = data.total || rows.length;
    this.setPageData(this._datagrid.getPageIndex(), this._datagrid.getPageSize());
}

相应的,还需要在 setPageData() 里修改一个 setTotalCount() 的实参

grid.setTotalCount(this._total);

搞定!

源代码 ClientPagination mini_clientpagination.js
const METHODS = ["setData", "load"];

class ClientPagination {
    static wrap(datagrid) {
        return new ClientPagination(datagrid);
    }

    constructor(datagrid) {
        this._datagrid = datagrid;
        this._origin = {};
        this.setup();
    }

    setup() {
        const grid = this._datagrid;
        const origin = this._origin = {};

        METHODS.forEach(name => {
            // 绑定到原对象的原方法
            origin[name] = grid[name].bind(grid);
            // 替换为本类中定义的新方法
            grid[name] = this[name].bind(this);
        });

        // 暂存事件处理函数,以便后面注销
        this._onBeforeLoad = this.onBeforeLoad.bind(this);
        grid.on("beforeload", this._onBeforeLoad);
    }

    destroy() {
        // 恢复原方法(来自 datagrid 类的 prototype)
        // 只需要删除附加到对象上的同名方法即可
        METHODS.forEach(name => {
            delete this._datagrid[name];
        });

        this._origin = {};
        this._datagrid.un("beforeload", this._onBeforeLoad);
        this._datagrid = null;
    }

    onBeforeLoad(e) {
        // 根据官方的解决方案而来
        const pageIndex = e.data.pageIndex;
        if (pageIndex < 3) {
            e.cancel = true;
        } else {
            // NOTE 一般来说不需要修改 url,直接通过 pageIndex 参数即可从后台获取不同页的数据
            // 这里因为是用的静态 JSON 数据,所以需要修改 url
            e.url = `data/page${pageIndex}.json`;
            return;
        }
        let pageSize = e.data.pageSize;
        this.setPageData(pageIndex, pageSize);
    }

    load(params, success, fail) {
        const grid = this._datagrid;
        const pageIndex = grid.getPageIndex();
        const url = grid.getUrl();

        params = $.extend(pageIndex < 3
            ? {}
            : { pageIndex: pageIndex, pageSize: grid.getPageSize() },
            params);

        const settings = {
            type: "get",
            dataType: "json",
            data: params
        };

        $.ajax(url, settings)
            .then(data => {
                this.setData(data);
                if (typeof success === "function") {
                    success(data);
                }
            }, () => {
                if (typeof fail === "function") {
                    fail();
                }
            });
    }

    setData(data) {
        const rows = Array.isArray(data)
            ? data
            : (data.data || []);

        this._data = rows;
        this._total = data.total || rows.length;
        this.setPageData(this._datagrid.getPageIndex(), this._datagrid.getPageSize());
    }

    setPageData(pageIndex, pageSize) {
        const allData = this._data;
        let start = pageIndex * pageSize;
        if (start >= allData.length) {
            start = 0;
            pageIndex = 0;
        }
        const end = Math.min(start + pageSize, allData.length);

        const pageData = [];
        for (let i = start; i < end; i++) {
            pageData.push(allData[i]);
        }

        const grid = this._datagrid;
        grid.setTotalCount(this._total);
        grid.setPageIndex(pageIndex);
        grid.setPageSize(pageSize);
        this._origin.setData(pageData);
    }
}
测试页面 index.html




    Client Pagination
    
    



    
序号
名称

当然还有 data 目录下的数据源 all.jsonpage3.json

all.json 中是前3页的数据

page3.json 中是第4页的数据

数据结构(仅结构

{
    "data": [],
    "total": 50
}

其中 data 的每一项结构

{
    "order": 1108,
    "name": "bridge"
}

完整的测试数据就自己拼吧,当然最好是还是用服务端数据,通过参数来返回不同的数据行。

我懒,懒得为了个实验还去写服务端

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91056.html

相关文章

  • miniui datagrid 户端分页解决方案

    摘要:官方的解决方案展示了客户端分页解决方案的基本思想,但是这个示例太过简单。原来是向设置了需要显示的所有数据行,不管分页比如可以一次显示出来条数据而现在,如果设置的数据量过大,则需要通过客户端分页来逐页显示。 官方的解决方案 官方在在线示例中给了一个简单的 client pagination 解决方案,代码就不贴了,这里说说它的基本思想和处理过程。 首先,是绑定一个 preload 事件,...

    darkbug 评论0 收藏0
  • 细说nui之datagrid

    摘要:表格的刷新保留查询条件的刷新当前分页的数据更新,请使用也可以使用获取当前接口请求的参数。 本期我们要讲述一下最常见的布局————表格:如何引入datagrid组件(在文章的末尾)来个demo,调用的代码 let options = { container:.con,//表格的容器 paging:{//分页的相关配置,其他参数配置参考[诺诺组件之分页(旧版)][1] ...

    LeanCloud 评论0 收藏0
  • fsLayui数据表格使用

    摘要:是一个基于的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置实现数据请求,减少前端重复开发的工作。 fsLayui 是一个基于layui的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置html实现数据请求,减少前端js重复开发的工作。 GitHub下载 码云下载 测试环境地址:http://fslayui.itcto.cn css和js引用 公...

    Joyven 评论0 收藏0
  • fsLayui数据表格使用

    摘要:是一个基于的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置实现数据请求,减少前端重复开发的工作。 fsLayui 是一个基于layui的快速开发插件,支持数据表格增删改查操作,提供通用的组件,通过配置html实现数据请求,减少前端js重复开发的工作。 GitHub下载 码云下载 测试环境地址:http://fslayui.itcto.cn css和js引用 公...

    charles_paul 评论0 收藏0
  • EasyUI datagrid问题整理

    摘要:什么是是一种基于和的用户界面插件集合。为创建现代化,互动,应用程序,提供必要的功能。是个完美支持网页的完整框架。很简单但功能强大的。返回则取消该动作。该函数有下列参数要传递到远程服务器的参数对象。当检索数据成功时调用的回调函数。 什么是easyUI easyui是一种基于jQuery、Angular.、Vue和React的用户界面插件集合。easyui为创建现代化,互动,JavaScr...

    megatron 评论0 收藏0

发表评论

0条评论

shixinzhang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<