layui中table組件功能增強及優化

      《layui中table組件內存佔用不斷上升問題》在這篇文章中提到了table組件內存佔用問題。今天給出自己的優化方式。那篇文章已經提到了問題的核心。重複調用render()方法,該方法是一個全過程方法,包括配置的解析處理,組件的框架渲染,各組成部分的渲染,數據的填充等等。在重複調用時,大量的中間數據、對象沒有及時釋放導致內存一直上升。實際應用中是完全不需要每次全過程的構建。只需要重新獲取數據,更新部分相關ui部分,如:頁碼,記錄總數等等。

        查看源碼,可以看到獲取數據有單獨的方法:pullData。那麼在執行頁面查詢、及刷新時,只需要調用該方法即可。

      在table模塊中增加如下接口:

      //表格加載
  table.query=function(id,param){
      var config = getThisTableConfig(id); //獲取當前實例配置項
      if(!config) return;
      var that = thisTable.that[id];
      that.config = $.extend(true, {}, that.config, {where:param});
      that.page=1;
      that.pullData(that.page);
  };
  //表格刷新
  table.refresh=function(id){
      var config = getThisTableConfig(id); //獲取當前實例配置項
      if(!config) return;
      var that = thisTable.that[id];
      that.pullData(that.page);
  };

兩者的區別就是,查詢需要傳入新的查詢條件,同時將頁面設置爲1;而刷新不需要設置任何東西,只是單純的重新獲取一次數據。

第二點說下table表格的編輯功能。設置了編輯功能後,就可以直接在table中的單元格中編輯數據。並且原組件提供了一個編輯過程中的事件:單元格編輯時的change事件。這是一個內部事件處理。在這處理過程中對外提供了一個接口 edit(filter) 可以讓用戶進行再處理。但在 edit(filter)調用前,已經將輸入值設置到內部數據對象了。即這個對外接口已經無法影響編輯值了。而實際應用中更合理的情況是,在外部接口中會對數據進行校驗,根據校驗結果來決定是否將編輯值寫入內部數據對象。說到校驗好像table的編輯功能還沒有校驗功能。需要自己增強該功能。

既然要加校驗,一般情況是編輯完了,再進行校驗,校驗通過了,新值才能寫入內部數據對象同時界面也顯示新值。有些情況下可以邊輸入值邊校驗,如只能輸入整數。非整數可以即時校驗及時清除。但有些則不行,如小數。輸入小數點的時候,應該是合法的,可如果輸入了小數點後就不再輸入。有不是一個有效數字。這是即時校驗不好處理的。所以還不如統一放在輸入完成後進行校驗。也就是blur事件中。

原組件有blur事件處理,是內部處理。沒有對外提供接口。因此可以把change事件中的對外接口關閉,在blur中增加對外接口。

 //單元格編輯
    that.layBody.on('input', '.'+ELEM_EDIT, function(){   //change
      var othis = $(this)
      ,value = this.value
      ,field = othis.parent().data('field')
      ,key=othis.parent().data('key')
      ,col=that.getColsConfig(parseInt((key.split('-'))[2]))
      ,index = othis.parents('tr').eq(0).data('index')
      ,data = table.cache[that.key][index];
      
      //data[field] = value; //更新緩存中的值 
      
      var callRtn=layui.event.call(this, MOD_NAME, 'edit('+ filter +')', commonMember.call(this, {
        value: value
        ,field: field
        ,col:col
      }));

 

}).on('blur', '.'+ELEM_EDIT, function(){
      var templet
      ,othis = $(this)
      ,value = this.value
      ,thisElem = this
      ,field = othis.parent().data('field')
      ,key=othis.parent().data('key')
      ,col=that.getColsConfig(parseInt((key.split('-'))[2]))
      ,index = othis.parents('tr').eq(0).data('index')
      ,data = table.cache[that.key][index];
      
      //add 2020.4.10
      var callRtn=layui.event.call(this, MOD_NAME, 'afterEdit('+ filter +')', commonMember.call(this, {
        value: value
        ,field: field
          ,col:col
      }));
      if(callRtn!=null&&callRtn==false){
          return;
      }
      data[field] = value; //更新緩存中的值

afterEdit就是我們新增加的對外接口,原edit對外接口沒有關閉先留着。同時數據對象的更新也是放在afterEdit之後。且是根據對外接口的結果值來控制的。這爲校驗提供了條件。

還差一個條件。校驗需要校驗規則。校驗規則如何配置?很自然配置在列配置對象中好理解。

width:150,align:'right',edit:'text',error:'應爲整數',dataType:'Number'},

列配置是組件的入口,是一個很好的擴展點。

現在需要回調接口:afterEdit中來獲取校驗規則。原組件在調用回調方法時,主要傳入當前編輯數據,tr對象之類。沒有列配置對象。所以這是一個需要我們修改的地方

 ,col=that.getColsConfig(parseInt((key.split('-'))[2]))

 var callRtn=layui.event.call(this, MOD_NAME, 'afterEdit('+ filter +')', commonMember.call(this, {
        value: value
        ,field: field
          ,col:col
      }));

在到回調方法中應用規則


                table.on('afterEdit(tab-car-run)', function(obj){
                 
                    var col=obj.col
                    ,tr=obj.tr
                    ,td=$(tr).find("td[data-field='"+obj.field+"']");
                    var rst=validator.validate(obj.value,col.require,col.dataType);
                    if(!rst){
                        layer.tips(col.error||'數據格式不正確', td,{tips: 3});
                    }
                    return rst;
                });

還有一個增強的地方:編輯按數據後,需要知道哪些行的數據是被編輯過。這樣做保存數據到後臺時,更方便。而不是將所有數據都覆蓋式的保存。

還有其他組件也有優化和增強的地方,以後細說。感覺這套組件缺乏實際項目的錘鍊。簡單應用可能沒什麼問題,大點的應用要有采坑的準備和填坑的能力

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章