miniui datagrid 的客户端分页解决方案 - CS连系

在前一篇,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

<!DOCTYPE html />
<html>

<head>
    <title>Client Pagination</title>
    <link href="miniui/themes/default/miniui.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
        body {
            margin: 0;
            padding: 5px;
        }
    </style>
</head>

<body>
    <div class="mini-fit">
        <div class="mini-datagrid" id="grid" pageSize="6" url="data/all.json" style="height: 100%">
            <div property="columns">
                <div type="indexcolumn"></div>
                <div type="checkboxcolumn" width="32"></div>
                <div field="order" width="60">序号</div>
                <div field="name" width="80">称号</div>
                <div field="autofit" width="auto"></div>
            </div>
        </div>
    </div>
    <script src="jquery-1.6.2.min.js"></script>
    <script src="miniui/miniui.js"></script>
    <script src="mini_clientpagination.js"></script>
    <script>
        mini.parse();
        const grid = mini.get("grid");
        ClientPagination.wrap(grid);
        grid.load();
    </script>
</body>

</html>

固然另有 data 目录下的数据源 all.jsonpage3.json

  • all.json 中是前3页的数据
  • page3.json 中是第4页的数据

数据构造(仅构造

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

个中 data 的每一项构造

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

完全的测试数据就本身拼吧,固然最好是照样用服务端数据,经由过程参数来返回差别的数据行。

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

    原文作者:边城
    原文地址: https://segmentfault.com/a/1190000007266979
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞