table纯data模式下的新增与删除

讨论 已结
65 2540
岁月小偷
悬赏:50飞吻
有没有觉得工具监听给他们的提供的del方法不靠谱,如果对table的静态数据新增还有修改有疑问的可以看看,其实这个使用场景不多,也没怎么重视,一般来说table都是设置url发请求,那么新增修改删除都是跟server交互然后reload表格就可以了,没必要自己还去处理什么缓存数据然后更新table里面的显示内容之类的。但是如果是data模式,那么新增修改删除操作的其实就是静态数据,然后也是reload就可以了,也许会说工具条的监听中给我们的参数中自带del和update,为啥不直接用,update其实还是可以用的只不过目前对templet为方法实现的支持update之后有问题而已。后续应该会修复的一个bug。del就真的呵呵了,见过删除了之后总条数不变的删除吗?见过删除之后翻页再翻回来还能自己回来的吗?只能说简直了这操作。
今天不改源码,因为完全舍弃监听提供的del。其实最主要的思路还是操作数据然后reload,所有的增删改都只要对数据进行操作就可以了,渲染的工作留给控件本身,不需要总是想着如何操作table的dom给添加一行删除一行,修改某一行的某一个td之类的,更不可取的思路就是只想着这些dom的操作完全不考虑数据方面的处理。
新增效果图(完整测试代码: https://pan.baidu.com/s/1a_FxGYiJhx8-G6JjeefDmA

删除数据效果图

除了数据处理之外为了得到更好的体验,一般来说就有另外一个问题就是如何确定reload的时候的page的curr
关键代码
// 工具监听
table.on('tool(testTable)', function (data) {
switch (data.event) {
case 'del':
// 只做测试数据的删除用,url的删除一般都是发交易然后重载表格就可以了
var tableObj = tableIns;
var config = tableObj.config;
var dataTemp = config.data;
var page = config.page;
// 得到tr的data-index
var trElem = data.tr.first();
var index = trElem.data('index');
// 计算出在data中的index
var dataIndex = index + page.limit * (page.curr - 1);
// 删除对应下标的数据
dataTemp.splice(dataIndex, 1);

// 新的页数
var pageNew = Math.ceil(dataTemp.length / page.limit);

// 重新接收reload返回的对象,这个很重要
tableIns = table.reload(config.id, $.extend(true, {
// 更新数据
data: dataTemp
}, config.page ? {
// 如果删除了数据之后页数变了,打开前一页
page: {
curr: page.curr > pageNew ? ((page.curr - 1) || 1) : page.curr
}
} : {}));
break;
default:
break;
}
});

// 新增一条记录
$('#createNew').click(function () {
// debugger;
var tableObj = tableIns;
var config = tableObj.config;
var dataTemp = config.data;
dataTemp.push({id: 'new' + new Date().getTime()});
tableIns = table.reload(config.id, $.extend(true, {
// 更新数据
data: dataTemp,
}, config.page ? {
// 一般新增都是加到最后,所以始终打开最后一页
page: {
curr: Math.ceil(dataTemp.length / config.page.limit)
}
} : {}));
});
回帖
  • 虽然用不上这个功能,但是感觉好厉害![嘻嘻] 向大神学习!
    0 回复
  • @4流马鹿 表单里面的按钮如果是一个普通的按钮,要给他强制的设置一个type="button"不然部分浏览器默认是submit的,点击就提交表单了造成页面的刷新
    1 回复
  • //监听工具条
    table.on('tool(test)', function(obj){ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
    var data = obj.data; //获得当前行数据
    var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
    var tr = obj.tr; //获得当前行 tr 的DOM对象

    if(layEvent === 'detail'){ //查看
    //do somehing
    } else if(layEvent === 'del'){ //删除
    layer.confirm('真的删除行么', function(index){
    obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
    layer.close(index);
    //向服务端发送删除指令
    });
    } else if(layEvent === 'edit'){ //编辑
    //do something

    //同步更新缓存对应的值
    obj.update({
    username: '123'
    ,title: 'xxx'
    });
    }
    });
    这是官方示例,我感觉没啥问题啊
    obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
    有明确的说明是操作DOM
    0 回复
  • @艾大叔是土匪 如果你认为总共1000条数据,删除了n条之后还是1000条数据,一切换页面这些数据又回来了,这些都是正常的没问题的,完全可以用obj.del玩一玩,直接无视我的就可以了。我这个只针对认为删除数据就是删除数据,每删除一条就会失去一条数据而且切换了也不会再回来的这个逻辑才是正常的逻辑的人准备的。
    0 回复
  • @菜鸟程序猿 [嘻嘻] 彼此彼此
    0 回复
  • @岁月小偷 其实就是删除只删除DOM,没有删除数据源,我觉得对于一个框架来说,这根本不叫问题,开发者手动删一下也不是不可以啊。
    0 回复
  • @艾大叔是土匪 这个见仁见智了。没说他做得不对,我直说他这个只是一个玩具,玩玩就可以了,分享这个出来也只是为了给那些把这个玩具当生产力工具来使被坑的人一个解决的思路,还有一个认清楚他提供的到底是一个什么东西。
    0 回复
  • kalowei
    2018-6-15
    兄弟,想问一下你,你一边你自定义的css和js都是放在哪里的?
    比如我用了layuiadmin这个后台模版,有如下这么两个大目录:


    js应该是放在controller文件吗?
    css呢?
    而且我们自定义的js一般怎样才算规范呢?比如官网说的layui.define()定义,这个什么时候使用?


    像我这样定义的话,我想对某个模块重用呢???
    以前都是:
    $(function(){
    show(); //调用
    });

    function show(){

    }
    0 回复
  • kalowei
    2018-6-15
    真不好意思呢,打扰一下你的帖子,因为我确实在这个点上有点迷茫。所以向你请教一下
    0 回复
  • 这一块要好好看看官方的文档额。里面写的很详细 http://www.layui.com/doc/base/modules.html#extend layui的基础和组件是layui其他任何产品的底层支撑。不搞明白这个也就不好弄其他的,如果弄明白了其实不管用layuiIM或者layuiAdmin都是差不多的,比如你说的想要加自己的扩展,一方面可以controller的文件家里面,然后你就用里面的一个js作为参考修改你自己的js,后面页面直接layui.use你自己的js这个就可以了,如果你想把你自己的js跟admin自带的给区分开来自己开了个文件夹存放,那么需要在第一次use之前需要给layui.extend一下,然后后面就指定自己的路径,注意是相对于controller的相对路径就好。

    当然也可以extend一个其他服务器上的文件
    0 回复
  • kyrie
    2018-7-13
    尊敬的大佬,帮解答一个问题哈
    自定义表格

    复选框监听事件

    复选框选中就新增一行

    结果第二次点击复选框的时候提示data未定义
    0 回复
  • @kyrie 囧,称呼吓到俺了[偷笑] 太隆重啦这。这个VM是什么呢?弹出的是一个iframe吗?但是感觉重点不是这里,你可以在

    这里写个debugger浏览器调试一下,看看执行createNew的时候tableGrid里面是啥,有没有data这个属性,你说的第二次点击不行,那第一次点击是可以吗?
    0 回复
  • kyrie
    2018-7-13
    @岁月小偷 vm是vue对象 弹出的type是页面层 为什么第一次dataTemp不为null,第二次就为null呢?
    0 回复
  • 表格确实很头痛,console.log了一下才发现原来layui删除之后,原来的数据成了空数组了。。
    新增行真让人头痛
    0 回复
  • @胖胖大魔王 嗯嗯,所以要定位准确哈,对他提供的这个obj.del()到底是个啥玩意,能派上用场不。就我的个人看法它就是一个玩具,远的url的不说,即使是data的模式,也仅仅是看个热闹就够了,删除会弹出,然后删了会去掉这一行数据,看着挺热闹的挺好的,实际上分页条数不变,当前页面数据不会减掉这条数据之后补充后面页面的数据进来,它之所以要设置缓存的当前下标的数据为空,最主要的就是删除了这个tr之后后面再删除,其实那一条数据的tr绑定的data-index记录的还是删除之前的index所以,它也没办法直接splice掉前面删除的,不然后面的tr删除的时候index还是旧的就可能出现删错行,或者没找到数据的情况,总之这个不是一个单一的问题哈,所以总结来说就是obj.del()根本在我眼里是完全用不上的一个玩意,还是要自己封装一下。
    0 回复
  • kyrie
    2018-8-16
    @岁月小偷
    今天突然想起来这个问题还未解决


    0 回复
  • kyrie
    2018-8-16
    @岁月小偷
    这是第一次点击时tableGrid的打印值
    0 回复
  • @kyrie 这样子看不出什么问题额,可以的话把这个出问题的代码整个给一下,放到云盘之类的,我下下来给你看看整体的,
    0 回复
  • kyrie
    2018-8-16
    @岁月小偷 稍后发给你!稍等!
    0 回复
  • kyrie
    2018-8-27
    @kyrie 我是集成在项目里面 单独分离出来不好整理


    一直困扰着我
    0 回复
  • kyrie
    2018-8-27
    0 回复
  • @kyrie 嗯嗯刚刚才收到,看来现在社区有bug额,你的上一条信息,我没有收到消息提醒。神奇了,
    0 回复
  • kyrie
    2018-8-27
    @岁月小偷 往上翻 我回复自己了 不好意思 我艾特你上面就是的
    0 回复
  • kyrie
    2018-8-27
    0 回复
  • kyrie
    2018-8-27
    @岁月小偷
    数据更改后我接着打印有数据
    0 回复
  • @kyrie 这个是我的发的帖子,正常来说不管其他用户有没有@ 我, 我都应该能收到消息提醒的,但是出现了木有的情况额,我另外一个帖子也是,今天才发现有几个人在里面品论了但是我完全没印象收到过消息提醒。这个应该是个bug。题外话了,你这个问题我这边估计也没办法怎么调,建议你自己在这个打个debugger,看看他为啥第一次可以,然后到了第二次不行,我怀疑是不是这个reload的时候return错了,还有一个你render的时候是怎么写的,还有一个是那些地方调用了这个createNew,它传过来的参数是啥?
    0 回复
  • kyrie
    2018-8-27
    @岁月小偷

    reload之后我接着打印有数据
    但是我接着点击createNew时又提示我config.data未定义
    0 回复
  • @kyrie 那就应该好好看看createNew的时候传参是什么,这个tableGrid是不是全局的之类的,
    0 回复
  • kyrie
    2018-8-27
    @岁月小偷 如果不是全局的话 那它应该和第一次打印一样啊 不应该提示未定义啊
    0 回复
  • @kyrie 嗯嗯,确实很奇怪,不过没有一个完整的代码真心看不出来到底是怎么了,可以的话把你这个出错的代码的文件存到你的网盘上我下下来整体的看看,有一些问题得看全面的,一直看出错的地方的代码未必能看出问题来的。
    0 回复