• 直播造轮子-分页


    虽说分页已经被人们撸过无数个了,但是目测还没有一个有我撸的好的》-《

    不信我撸给你看。

    一、应用场景

    我需要这样一个分页组件,它有首页、上一页、上一组、一组页码、下一组、下一页、末页,可以自由控制一组页数,还得是个组件。

    裸着的时候长得像这样:

     二、撸起袖子,甩开膀子

    1、先想好工作原理

    已知:条目总数:total,页长:pageSize,初始页码:pageIndex。

    目的:根据已知条件算出是否有首页(first)、上一页(prev)、上一组(blockLeft)、一组页码(当前页pageIndex居中)(pageBlock)、下一组(blockRight)、下一页(next)、末页(end)。 

    像我这样初中开始数学就没及格过的都能算出来,我就不啰嗦了,直接放个伪代码:

    /*fileds*/
    var total,pageSize,pageIndex,halfBlockSize;
    var pageCount = Math.ceil(total/pageSize);
    var pageBlock = function(){
          for: pageIndex-halfBlockSize->pageIndex+halfBlockSize{
            if:(item>0&&item<pageCount) push to array
          }
          return array;          
    };
    var hasBlockLeft = (pageBlock[0]-1)>halfBlockSize;
    var hasBlockRight = (pageCount-pageBlock[length-1])>halfBlockSize;
    var hasPrev = pageIndex>1;
    var hasNext = pageIndex<pageCount;
    
    /*click functions*/
    var prev = function(){pageIndex--;}
    var first = function(){pageIndex = 1;}
    var blockLeft = function(){pageIndex =pageIndex-halfBlockSize*2;}
    var index = function(){pageIndex = index;}
    var blockRight = function(){pageIndex = pageIndex+halfBlockSize*2;}
    var end = function(){pageIndex = pageCount}
    var next = function(){pageIndex++;}

    核心"算法"已经出来了,那么接下来渲染界面就可以了,可以用js/jquery/vue/react等等操作dom,我比较土,用knockoutJS。

    view:

    <div data-bind="with:pager">
        <a href="javascript:void(0)" data-bind="visible:pageCount()>1,click:first">First</a>
        <a href="javascript:void(0)" data-bind="visible:hasPrev,click:prev">< Prev</a>
        <a href="javascript:void(0)" data-bind="visible:hasBlockLeft,click:blockLeft"><<</a>
        <!--ko foreach:pageBlock-->
        <a href="javascript:void(0)" data-bind="text:$data,click:$parent.index.bind($data)">Index</a>
        <!--/ko-->
        <a href="javascript:void(0)" data-bind="visible:hasBlockRight,click:blockRight">>></a>
        <a href="javascript:void(0)" data-bind="visible:hasNext,click:next">Next ></a>
        <a href="javascript:void(0)" data-bind="visible:pageCount()>1,click:end">End</a>
    </div>

    viewmodel:

    define(['knockout'], function (ko) {
        var pager = function (total, pageSize, pageIndex, halfBlockSize, getPageData) {
            var self = this;
            self.total = ko.observable(total);
            self.halfBlockSize = halfBlockSize == null ? 2 : halfBlockSize;
            self.pageSize = ko.observable(pageSize);
            self.pageIndex = ko.observable(pageIndex == null ? 1 : pageIndex);
            self.pageCount = ko.computed(function () {
                return Math.ceil(self.total() / self.pageSize());
            });
            self.hasNext = ko.computed(function () {
                return self.pageIndex() < self.pageCount() && self.pageCount() > 1;
            });
            self.hasPrev = ko.computed(function () {
                return self.pageIndex() > 1 && self.pageCount() > 1;
            });
            self.pageBlock = ko.computed(function () {
                var start = self.pageIndex() - self.halfBlockSize;
                var len = self.pageIndex() + self.halfBlockSize;
                var arr = [];
                for (var i = start; i <= len; i++) {
                    if (i > 0 && i <= self.pageCount()) {
                        arr.push(i);
                    }
                }
                return arr;
            });
            self.hasBlockLeft = ko.computed(function () {
                return (self.pageBlock()[0] - 1) > self.halfBlockSize;
            });
            self.hasBlockRight = ko.computed(function () {
                return (self.pageCount() - self.pageBlock()[self.pageBlock().length - 1]) > self.halfBlockSize;
            });
            self.isInited = false;
            self.handlePageIndex = ko.computed(function () {
                if (!self.isInited) {
                    self.isInited = true;
                    return self.pageIndex();//Let ko know this function is with self.pageIndex();
                }
                getPageData(self.pageIndex());
                return 0;
            })
    
            /*click functions*/
            self.prev = function () {
                self.pageIndex(self.pageIndex() - 1);
            };
            self.first = function () {
                self.pageIndex(1);
            };
            self.blockLeft = function () {
                self.pageIndex(self.pageIndex() - self.halfBlockSize * 2);
            };
            self.index = function (i) {
                if (i == self.pageIndex()) {
                    getPageData(i);//While current pageIndex was clicked,I'll call the function manually.
                } else {
                    self.pageIndex(i);//While current pageIndex was changed,it'll call the function automatically.
                }
            };
            self.blockRight = function () {
                self.pageIndex(self.pageIndex() + self.halfBlockSize * 2);
            };
            self.end = function () {
                self.pageIndex(self.pageCount());
            };
            self.next = function () {
                self.pageIndex(self.pageIndex() + 1);
            }
            /*click functions*/
        };
        return {
            vm: pager
        }
    });

    遵循AMD规范,方便异步加载。

    css的话,自由发挥吧。这里就不贴了。

    如此已经可以当成组件来用,加载view和viewmodel即可,例如:

    render('view');

    require(['knockout','pager'],function(ko,pager){ var pg = new pager.vm(100, 1, 15, 5, function (i) { console.log("I'm get " + i); }); })
  • 相关阅读:
    4.2网络层提供的两种服务
    4.1网络层概述
    MATLAB曲面插值及交叉验证
    python爬虫成长之路(二):抓取代理IP并多线程验证
    KNN识别图像上的数字及python实现
    python爬虫成长之路(一):抓取证券之星的股票数据
    YARN环境搭建 之 一:CentOS7.0系统配置
    高效学习方法总结
    《立委随笔:机器学习和自然语言处理》
    XenServer安装虚拟机先扩容存放ISO镜像文件
  • 原文地址:https://www.cnblogs.com/kexxxfeng/p/5718913.html
Copyright © 2020-2023  润新知