scala版本的grails分页代码

大家平时见过这样的分页么?见过的话知道怎么写么?没见过的话有思路么?

就本人的话,在用grails时见到了这个强大的分页功能,但是对于里面的代码和思路一知半解。
今天心血来潮想要重新理解下原理,所以花了点时间分析了下实现,最终在回家的地铁上基本明白了其中的逻辑,特此写文分享。

在展示最终的scala代码之前,先说下分页中的几个概念,同时为了方便,这里取用grails中的变量名:

currentStep:当前页
lastStep:最后页
(firstStep):第一页,隐式常量
beginStep: 这种分页的起始页,可以认为是..之后的数字
endStep:这种分页的结束页,可以认为是第二个..之前的数字
maxSteps:控制这种分页的beginStep到endStep之间的数量的参数

有了这些参数之后,先看简单的部分:
previous:currentStep > firstStep的话就显示
1: beiginStep > firstStep的话就显示
第一个..:beginStep > (firstStep + 1)的话就显示
第二个..:endStep < (lastStep - 1)的话就显示 lastStep:endStep < lastStep的话就显示 next:currentStep < lastStep的话就显示 其实有了这些,简单的

就可以做了,不过grails的这个分页强大的地方在于maxSteps、beginStep和endStep。以下是beginStep和endStep的groovy代码,也是一直困扰我的地方。

这里在做什么操作呢?经过一段时间思考,我认为这段是在剪裁beginStep..endStep的区间。剪裁的理由显而易见,当前页可能就是第一页或者最后一页。遇到这种情况,beginStep肯定不能从负数开始,endStep页不能超过最后一页。但是grails这段代码是怎么剪裁的呢?

首先是判断左边,做向右移动操作,其次是判断右边,做向左移动操作,同时判断是否超过左边界了,如果超过了剪裁。 你可能会问,为什么判断右边时剪裁了而判断左边时没剪?个人认为可能是因为“重复”而被去掉了,那么是否会出问题呢?看上图,需要剪裁的场景没出问题。 另外个人认为判断左边时剪裁可以做,多做没啥问题,因为之后直接跳过右边的判断了。还有需要注意的是判断左边时没办法判定那种左边在范围内,右边在范围外的情况,所以单独的右边界判断是必须的。 虽然这段逻辑运行起来没太大问题,但是有点难以理解。我在用scala模拟时用的是另一个方法:

我把剪裁分为四种情况(左边和左边界判定有两种情况,右边和右边界判定有两种情况),剪裁结果如下

左边判定 右边判定 处理
firstStep <= beginStep endStep <= lastStep 无剪裁
firstStep <= beginStep endStep > lastStep 向左边移动,存在剪裁可能
firstStep > beginStep endStep > lastStep 全剪裁
firstStep > beginStep endStep <= lastStep 向右边移动,存在剪裁可能

虽然比起前面代码可能要多一些,不过更直观。
最后是scala代码: