vue2.0结合DataTable插件实现表格的动态刷新

今天周六啊!一想到我的凤九和东华要生小滚滚,我就归心似箭无心敲代码!

产品提出的需求是这样的,很普通的一个统计server端task完成率和状态的表格,要自动刷新其中的数据,并且当单个task完成的时候report给server端,看起来好easy好easy的一个需求啊!且听我说完哈!

我这边使用的是框架是vue,表格自然用v-for渲染,然后我们这边分页搜索神马的都是前端弄,也就是说后端只管把一大坨数据塞到前端,然后前端自己组装分页器和完成模糊搜索,所以啊,我之前用的是DataTable这个插件,组装好的表格效果如下,看着没毛病哈!

可是涉及到自动刷新就有问题了,因为每次获取数据都是全量数据,用dataTable组装表格的话,就必须要组装好的表格destroy掉,然后再v-for再DataTable()组装..页面会一直一直闪!体验好差的说!

我只想出了一个比较笨的方法解决这个局部刷新的问题,大家要是有更好的方法一定要告诉我!!上代码!

1.v-for只渲染不变的数据,比如名字备注之类的,一直刷新的字段比如状态和完成率都为空,就这样,只用DataTable首次渲染表格

2.setRefresh是一个定时器,每隔1s就递归调用一次自己,query全量数据,存放到originTableList里

3.updateRefreshStatus是用原生的js去获取每行的dom,然后innerText去改变其值

4.reportTaskComplete是当当前这个task完成率达到100%就汇报给server

5.checkTaskRefresh是递归检查所有的任务,把完成的任务放到completeTaskList,如果全都完成了就把定时器清除掉

6.beforeRouteLeave是vue router的方法,在离开路由之后清除计时器

template

 

 

 

 

js

 

methods: {

    initRecordTable: function(){
        $('#main-table').DataTable({
            "paging": true,// 开启分页
            "pageLength": 10,//每页显示数量
            "lengthChange": true,//是否允许用户改变表格每页显示的记录数
            "searching": true,//搜索
            "ordering": true,//排序
            "info": true,//左下角 从 1 到 5 /共 23 条数据
            "autoWidth": true,
            // "scrollX": "100%",//表格的宽度
            // "scrollY": "200px",//表格的高度
            "scrollXInner": "100%",//表格的内容宽度
            // "bScrollCollapse":true,//当显示的数据不足以支撑表格的默认的高度时,依然显示纵向的滚动条。(默认是false) 
            "aaSorting": [
                [3, 'asc']
            ],
            "language": {
                "sInfoEmpty": "没有数据",
                "sZeroRecords": "没有查找到满足条件的数据",
                "sInfo": "从 _START_ 到 _END_ /共 _TOTAL_ 条数据",
                "sLengthMenu": "每页显示 _MENU_ 条记录",
                "sInfoFiltered": "(从 _MAX_ 条数据中检索)",
                "oPaginate": {
                    "sFirst": "首页",
                    "sPrevious": "前一页",
                    "sNext": "后一页",
                    "sLast": "尾页"
                }
            },
        });
    },
    initQuery: function(){

        // status 和 rate两个字段是实时刷新的
        // dataTable摧毁和tableList赋值都砸在promise里完成
        // tableList只初始化的时候赋值一次 然后就不动了 用原生js去改变表格内的status字段
        let mySelf = this;
        let callback = function(){
            if($('#main-table').DataTable()){
                $('#main-table').DataTable().destroy()
            }
            mySelf.tableList = util.deepClone(mySelf.originTableList);
        }
        let queryTablePromise = mySelf.queryTable(callback);
        let promiseList = [];

        mySelf.clearRefresh();
        promiseList.push(queryTablePromise);
        Promise.all(promiseList).then(function (result) {
            console.log('ajax全部执行完毕:' + JSON.stringify(result)); // ["Hello", "World"]
            //renderTable函数只在首次进入页面时调用 1.毁掉dataTable插件 2.加载一次表格更新状态和完成率 3.调用自动刷新

            mySelf.renderTable();
            mySelf.updateRefreshStatus();
            mySelf.setRefresh();
        });

    },
    switchRefreshStatus: function(){
        let mySelf = this;
        let status = mySelf.refresh.status;
        let text = (status==true)?'关闭':'开启';
        let confirmCallback = null;

        if (status==true){
            confirmCallback = function(){
                mySelf.refresh.status = false;
            }
        }
        else{
            confirmCallback = function(){
                mySelf.refresh.status = true;
                mySelf.setRefresh();
            }
        }
        util.showConfirm('确认要' + text + '自动刷新么?',confirmCallback);

    },
    checkTaskRefresh: function(){
        let mySelf = this;
        let originTableList = mySelf.originTableList;
        let taskAllComplete = true;
        // console.log(JSON.stringify(mySelf.originTableList));
        originTableList.forEach(function(item,index,array){
            let completeTaskList = mySelf.refresh.completeTaskList;
            let completeRate = item.completeRate;
            //当前task完成 report给后端
            if (Number.parseInt(completeRate) == 1){
                // 若任务完成列表 没有这个TaskId 则发送请求
                if (!completeTaskList.includes(item.id)){
                    console.log(item.id + "任务完成了!并且不存在于任务完成列表,现在发送完成请求!");
                    mySelf.reportTaskComplete(item.id);
                    mySelf.refresh.completeTaskList.push(item.id);
                }
            }
            else{
                taskAllComplete = false;
            }

        });

        if(taskAllComplete){
            console.log('全部任务都完成了!')
            return true;
        }

        return false;
    },
    setRefresh: function(){
        let mySelf = this;
        let status = mySelf.refresh.status;
        let interval = mySelf.refresh.interval;

        // 如果所有任务都完成了 则停止发送ajax请求 并更新最后一次
        if (mySelf.checkTaskRefresh()){
            console.log('更新最后一次表格!')
            mySelf.updateRefreshStatus();
            return false;
        }
        
        // console.log('refresh')
        if (status){
            mySelf.refresh.timer = setTimeout(function(){

                let queryTablePromise = mySelf.queryTable();
                let promiseList = [];
                promiseList.push(queryTablePromise);
                Promise.all(promiseList).then(function (result) {
                    console.log('ajax全部执行完毕:' + JSON.stringify(result)); // ["Hello", "World"]
                    mySelf.updateRefreshStatus();
                    mySelf.setRefresh();
                });

            },interval);
        }
        else{
            mySelf.clearRefresh();
        }

    },
    updateRefreshStatus: function(){
        console.log('更新刷新状态')
        let mySelf = this;
        let mainTable = document.getElementById("main-table");
        let originTableList = mySelf.originTableList;

        originTableList.forEach(function(item,index,array){
            let trClassName = "id-" + item.id;
            // console.log(trClassName)
            // 获取当前页面展示的所有tr
            let trDom = mainTable.getElementsByClassName(trClassName)[0];
            // console.log(trDom)
            // 局部刷新个别字段
            if (trDom){
                let tdRate = trDom.getElementsByClassName("rate")[0];
                let tdStatus = trDom.getElementsByClassName("status")[0];
                tdRate.innerText = item.completeRate;
                tdRate.className = (item.status == "1")?"text-info rate":((item.status == "2")?"text-success rate":"text-danger rate");
                tdStatus.innerText = (item.status == "1")?"刷新中":((item.status == "2")?"刷新完成":"刷新失败");
                tdStatus.className = (item.status == "1")?"text-info status":((item.status == "2")?"text-success status":"text-danger status");
            }

        });

    },
    clearRefresh: function(){
        let mySelf = this;
        console.log('clear timer');
        clearTimeout(mySelf.refresh.timer);
    },
    queryTable: function(callback){

        let mySelf = this;
        let promise = new Promise(function (resolve, reject) {
            let url = pars.domain + "/api.php?Action=xxxxxxx&t=" + (new Date).getTime();
            $.get(url, function(res) {
                if (res.code == 0) {
                    let resData = res.list;
                    resData.forEach(function(item,index,array){
                        let info = item.info;
                        let completeCount = info.completeCount;
                        let total = info.count;
                        item.completeRate = ((completeCount/total)*100).toFixed(2) + "%";
                    });
                    // console.log(JSON.stringify(resData))

                    mySelf.originTableList = resData;
                    if (callback){
                        callback();
                        
                    }
                    
                    resolve('queryTable完成!');
                }
                else{
                    util.showDialog('error',"接口调用失败,报错信息为:" + res.message);
                }
            }, "json");
        });
        return promise;

    },
    renderTable: function(){

        let mySelf = this;

        mySelf.$nextTick(function(){
            mySelf.initRecordTable();
            util.hideLoading();
        })

    }

},
beforeRouteLeave (to, from, next){
    let mySelf = this;
    mySelf.clearRefresh();
    next();
},

 

 

 

整体的效果如下,功能整体是实现了,但是感觉好笨的说,大家要是有好办法一定要告诉我哈!!

vue2.0结合DataTable插件实现表格的动态刷新_第1张图片

你可能感兴趣的:(vue2.0结合DataTable插件实现表格的动态刷新)