关于 table 的 checkbox 跨页状态保存的一种实现方式

讨论 未结 精帖
35 1409
岁月小偷
悬赏:80飞吻
首先表达一下感谢,没想到周末发了一个帖子贤心大大这么重视连夜发布了一个layui和admin的小版本([偷笑] 踩到点上而已),处理掉一些细节的问题,并且放出了2.5的重磅预告,非常值得期待。
更新于2018年11月4日15:37:10
感谢社区的小伙伴@肥喵叔叔 使用了这个tablePlug并且提出了一个遇到的问题 https://fly.layui.com/jie/43388/ ,让我意识到起初的一个不合理的设定,本来想着就是调整table.checkStatus这个方法,让它根据当前的表格是否有记住复选状态这个设定来返回,如果是不记住的还是以前的逻辑,返回的data还是当前页面的data,如果是记住状态的返回的data是记录的三种状态的数据的主键集合,然后isAll还是以前的逻辑,就是当前页面如果都选中了就是true,否则即为false。但是忽略了一个点就是以前代码中如果用到这个table.checkStatus中的data这么修改之后就会出现问题了,调整了一下,checkStatus返回的data还是以前的逻辑,如果是记忆模式的会提供另外一个属性status如下:
目前支持的新增的配置项:
1、checkStatus

2、colFilterRecord
更新于2018年11月2日11:32:48
再送另外一个实用的功能,提供多一个配置项colFilterRecord,既可以设置是否记住字段筛选,可以设置要不要,也能设置是local还是session。
更新于2018年11月1日09:18:32
大赞贤心,这么快又发了一个小版本解决一些社区中反应的bug,不会因为上个更新的时候说是收尾之更然后怕“打脸”就置之不理了等大版本再处理了,这个才是一个程序员应该有的负责的态度额,必须大赞。
然后说回本帖中的tablePlug,实际这个是个跟layui版本无关的插件,起码2.5.0以前都是ok的,2.5.0是未来的事情,如果是一个大版本,一般来说新增功能,然后部分代码也不一定会向下兼容,所以未来的事情不好说,但是只要没有翻天覆地的变化,这个tablePlug都是可用的,所以如果使用了本plug的小伙伴大可以放心的更新layui。然后下文提到的唯一的一处源码修改在2.4.5也得到修复了,而且修复的方式跟我原先的处理是一致的,所以更新之后,本plug是不会有任何不良的反应的。
更新于2018年11月1日09:23:34
还有一个忘记说明了,实际上本帖子里面的修改,标题只是阐述了它的一小部分的功能,实际上它不仅仅能够完成跨页面的记录,而是实实在在的完成一个叫做“复选记忆”的功能,也就是说不单单切换页面能够做到,reload也能够做到,只要你不想reset它不管你怎么reload它都还在的,当然你需要reset这个记忆,或者初始化它的时候,可以用tablePlug.tableCheck.reset或者tablePlug.tableCheck.init来重置或者重新初始化,在这个之前它都会保存着状态。
layui的小版本主要修复一些bug还有提供了autoSort的选择,支持以我们后台返回的数据为准(server排序)不会再走自带的sort排序,避免了可能最终显示的数据跟后台排序之后给我们的数据顺序之间不一致的问题,也保留了以前的前台本页面sort的逻辑,方便我们根据业务逻辑需要去设置。然后加多一个table.resize,对这个基础方法让我们更方便的在需要的时候去调整表格。文档也没过多的介绍,有的同学可能还不知道它有啥用,这里简单的介绍一下,这个基础的方法,在table生成的时候会监听window的resize然后调用这个基础方法去resize调整,但是这个不是主要的作用,主要是在需要去resize这个表格的时候,table提供给我们多一种选择,以前只有在窗口变化的时候它才会调整(自动列宽,百分比,固定列等),如果是iframe的可能感受不会很深,如果是单页面的,会有一个问题就是页面的容器之间有时候会调整大小,但是这个调整只是内部之间的作用,不会引起window的resize,那么有时候你hide一个主要的div啥的导致table所在的容器大小变化了,那么这时候是需要重新调整表格的,因为里面可能有自动列宽,百分比的列等等这些,那么以前的时候选择手段太少,基本就执行$(window).resize()来强制让它调整,但是这个就有点像杀鸡用牛刀的感觉了,为了调整表格,可能会引起一连串的连锁反应,毕竟不是只有table监听了window的resize,这时候table.resize就派上用场了,它有一个参数id,你可以指定resize某一个table也可以不传这个id,那它会去resize目前已经render过的所有的table。大概作用就是这个如果还是没啥感觉,需要的话明天找时间弄个测试例子出来试试,一般就清楚了。
跑题跑得好严重,回归正题
关于表格复选框列,目前只能做到单页状态记录,换了页回来就没了,要这种换了页面就不计以前的记录的这个使用场景应该也有,不过感觉需要记录的会更多,之前也发过帖子给出自己的一种实现的封装,不过可能说的也比较乱,看得云里雾里的,趁这次新版本,在尽量不修改源码的基础上弄了一个封装好的js给调用一下。
主要的意义:首先目前的版本没有这个功能,急着用就得自己扩展,其次假如后面有了,但是效果也不一定是自己想要的,那么还是可以自己扩展自己需要的,比如我要的一个是三种状态的,即有一些是默认就已经有的,有一种是以前没有,后面用户勾选上去的,另外一种是一开始有,后面用户点掉不要了这三种,然后有的业务逻辑又是想要得到的是不管以前的状态如何,就要当前已经选中的。所以后面即使layui支持了,也不知道能不能达到自己想要的。这里分享自己使用的方式出来看看有没有什么可以被借鉴的,或者有没有更好的方法来实现的。
源码修改的地方,只有一处,主要是为了解决table监听checkbox的时候点击单条记录进入监听中找不到当前行还有当前行的数据的问题。这个问题社区露脸率很高,可惜没有在2.4.4里面得到解决,但是监听checkbox如果都找不到这个复选框,找不到这一行找不到这一行的数据还有什么下文可以谈呢?所以首要的是修复这个问题,之所以会出现,是因为点击一个单项的复选框,如果点击之后切换了状态,不会对全选有任何影响的话,进入回调里面是正常使用的,但是一旦会影响到全选的状态,table目前是先同步全选的状态,里面的逻辑是更新全选的这个checkbox的checked然后form.render来更新但是与此同时被影响的就有这些单项的checkbox实际他们都被干掉然后重新生成新的节点,只不过这个过程对于我们人眼来说几乎是感受不到的,所以你看着以为没啥变化还是那个被点击的节点,但是实际已经在这dom树找不到原始的被点击的节点了,所以这个也没啥好的处理方式,改掉这个bug就可以,有更好的方式欢迎反驳我,但是如果说event.target的这个就算了,本身就是因为这个target已经不见了才出的问题。

暂时的处理是把原先写this的这两个地方换成原始的那个checkbox,这个节点不管form.render怎么执行它都稳稳当当的杵在那。
然后提供了一个tablePlug.js引用一下,很多处理都在里面封装处理的,这个如果看过我以前的那个laydatePro的帖子也会眼熟,很多原理都是差不多的,就是挟持原始的方法,然后在保证它以前的逻辑能够在合适的时候执行的情况下重构它。风险是有的,万一改坏了,那么原生的那些方法也会用不了,或者出现其他的bug。所以这里先说明一下,自己权衡,俺也是本着认真对自己代码负责的态度去完成自己的每一行代码的,不会蓄意搞破坏,但也不能保证没有bug,所以得先申明一下风险哈,当然还是比较有把握的说,俺能力还是凑合的,不然来句layui = '';之类的就直接友尽[阴险] [阴险]
不录动图了,300k的限制很难录好,直接用这个上去试试看: https://sun_zoro.gitee.io/layuitableplug/testTableCheckboxStatus
这里介绍一下测试页面,这几个箭头的地方关注一下,包括可以动态的切换模式等等

然后获得选中数据的还是以前的table.checkStatus这个,如果是跨页记录的得到的是如下的结构的


其中original是默认就有的,additional是新添加的选中,removed是原先有后面被点掉的。上面提到的三态记录。
如何使用
到这个测试的项目 https://gitee.com/sun_zoro/layuiTablePlug 的下载下载,引入tablePlug,剩下的就跟以前没太大的区别了,之前table.render怎么用还是怎么用,多了一个配置项的支持:

具体看里面的testTableCheckboxStatus.html和tablePlug.js
有需要补充的明天再补充了2018年10月30日22:17:54
回帖