07月15, 2016

记一次另类的分页

最近晚上天天加班,并不是加班写代码,而是带新人、指导新人完成具体的功能模块。感觉新人在js方面比较薄弱,然后顿感很大压力。

前两天,需求方提了一个需求,让小子顿感无奈,感觉实现起来好复杂。可能是我的算法比较薄弱,人比较蠢吧,写了一天多才实现,现给大家分享一下。

功能:给我的应用实现分页的功能。不同的应用有一个自己的Group组。来看一下最终要实现的结果:

功能图片

它的意思就是当第一页的B分类下的app排不下时,在第二页显示,第二页显示剩余的个数。

首先这个需求是建立在一页显示多少个app,以及一行显示多少个app是确定下来的。我们通过这两个值来进行排版的输出。

假设是一行2个app,一页显示4个。

json对象大概是长这个样子的:

var groupsList = [
    {
        groupId: 1,
        appList: [
            {
                appId: 2
            },
            {
                appId: 3
            },
            {
                appId: 4
            },
        ]
    },
    {
        groupId: 9,
        appList: [
            {
                appId: 8
            },
            {
                appId: 9
            },

            {
                appId: 10
            },
            {
                appId: 11
            },
            {
                appId: 12
            }

        ]
    },
    {
        groupId: 10,
        appList: [
            {
                appId: 18
            }
        ]
    }  
]

我们在做分页的时候,需要统计当前页的app应用是不是和每页显示的app个数相同。初看很简单,实则没那么轻松。

因为假设有2个类别的应用,第1个类别只有1个app,第二个类别有3个app,那么最终显示的结果第一页是第1个类别的1个app,第2个类别的前2个app,第二页是第2个应用的第3个app。

显然,第一页只有3个app,而每页显示的app个数最大为4,这两个是不相同的值。

所以第一个问题来了,怎么算出每个组它占用的最大app个数。如:

1个app,最大个数为2,
2个app,最大个数为2,
3个app,最大个数为4,
4个app,最大个数为4
...

我们通过余数来搞定这个事:

let countNum = (num, row_num) => {
        var mod = Math.ceil(num / row_num);
        return mod * row_num;
 }

这里的row_num是一行最大的app个数。

接下来,就是实现具体的功能了,在实现的过程中,主要要考虑两个问题:

  • 什么时候分页,即有一个变量做统计,当长度达到了,把currentPage变量+1
  • 数组的截取,这个是我纠结了很久的最大原因,想通之后就简单了

OK,我直接上代码吧:

/**
 * @author henryzp
 * @param row_num 一行显示的个数
 * @param page_num  一页显示的个数
 */
let handleData = (groupsList, row_num = 4, page_num = 12) => {

    let list = [], 
        i = 0, 
        current_page = 0, 
        total_num = 0,
        total_pre_num = 0;

    console.time("time");

    let countNum = (num, row_num) => {
        var mod = Math.ceil(num / row_num);
        return mod * row_num;
    }

    let getGroupNum = (index) => {
        let group = groupsList[index],
            appList = group.appList;
        return countNum(appList.length, row_num);
    }

    while(i < groupsList.length){

        let group = groupsList[i],
            appList = group.appList;

        let part_group;

        if(i > 0){
            total_pre_num = getGroupNum(i - 1);
        }

        for(let j = 0, len = appList.length; j < len; j += page_num){
            part_group = Object.assign({}, group);
            list[current_page] = list[current_page] || [] ;

            let slice_min = j,
                slice_max = j + page_num;

            if(total_pre_num != page_num){
                if(j == 0){
                    slice_max = slice_max - total_pre_num % page_num;
                }else{
                    slice_min = slice_min - total_pre_num % page_num;
                    slice_max = slice_min + page_num;
                }
            }

            console.log(slice_min, "----", slice_max)
            part_group.appList = part_group.appList.slice(slice_min, slice_max);

            list[current_page].push(part_group);
            console.log("长度:" + part_group.appList.length);
            total_num += countNum(part_group.appList.length, row_num);
            console.log("here, total_num: ", total_num);
            if(total_num == page_num){
                current_page ++;
                total_num = 0;
            }
        }    

        i++;

    }
    console.timeEnd("time");
    return list;
}

调用方式:

console.dir(handleData(groupsList, 2, 4));

本文链接:www.my-fe.pub/post/special-paging.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。