BootstrapTable 自定义列本地存储实践

BootstrapTable 自定义列本地存储实践

需求:

开放 BootstrapTable 的自定义表格列功能,前端记录用户选择,即在用户不清理浏览器历史记录的情况下,始终显示用户上一次的配置。

分析:

因项目基于 AngularJS1.5 实现,过滤了一部分老旧版本浏览器。所以选择使用 h5 的 LocalStorage 来记录用户的配置隐藏的列。

1. 查询 Bootstrap Table API,配置项 showColumns 用来配置是否可配置显示 / 隐藏列。

showColumns: true, // 显示下拉框勾选要显示的列

bootstrap-table.js 源码中,对于 showColumns 为 true 时,监听事件如下:

        if (this.options.showColumns) {
            $keepOpen = this.$toolbar.find('.keep-open');


            if (switchableCount <= this.options.minimumCountColumns) {
                $keepOpen.find('input').prop('disabled', true);
            }


            $keepOpen.find('li').off('click').on('click', function (event) {
                event.stopImmediatePropagation();
            }).find('span').off('checkChange').on('checkChange', function () {
                var ckeck = $(this).find('input').prop('checked');
                $(this)[ckeck ? 'addClass' : 'removeClass']('active');
            });
            $keepOpen.find('input').off('click').on('click', function () {
                var $this = $(this);


                that.toggleColumn(getFieldIndex(that.columns,
                    $(this).data('field')), $this.prop('checked'), false);
                that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));


                $this.parent('span').trigger('checkChange');
            });
        }

可知:通过代码触发 的"click" 事件,BootStrap Table 会自己完成列的隐藏 / 显示操作。

    //代码示例
    $(".bootstrap-table ul.dropdown-menu").find('input[data-field="APPName"]').trigger("click");

2. 基于 Bootstrap Table DOM 结构,可以遍历查询获取已经隐藏列的唯一标识 field。


BootstrapTable 自定义列本地存储实践_第1张图片

//代码示例
  var aTmpConfig = [];
  $(".bootstrap-table ul.dropdown-menu").find("input").each(function (i,v) {
    if(!$(v).parent().hasClass("active")) {
      aTmpConfig.push($(v).attr("data-field"));
    }
  });

3. 查询 Bootstrap Table API,有 onLoadSuccess 事件、onColumnSwitch 事件和 hideColumn(field) 方法,即可在 BsTable 成功加载数据之后触发隐藏列操作;在点击列显示 / 隐藏开关时,触发保存 userConfig 数据。

onLoadSuccess | load-success.bs.table | data | Fires when remote data is loaded successfully.
onColumnSwitch | column-switch.bs.table | field, checked Fires when switch the column visible.
hideColumn | field | Hide the specified column.

······
//代码示例
onLoadSuccess: function () {
  //get Config from LocalStorage
  $scope.$broadcast('hideColumn'+ '#' + tid, sField);
},
······

4. 查询 Bootstrap Table API,有 getHiddenColumns 方法,获取所有隐藏的列。在保存 userConfig 时可使用该方法。

//附bootstrap-table.js源码
BootstrapTable.prototype.getHiddenColumns = function () {
  return $.grep(this.columns, function (column) {
    return !column.visible;
  });
 };
设计:

初始化:
在 Bs.Table 的 onLoadSuccess 事件里,判断浏览器是否支持 LocalStorage 且用户是否对该 Bs.Table 有隐藏列配置,即 window.localStorage && window.localStorage.hasOwnProperty(tid+"BsTable")
获取该页面 Bs.Table 用户隐藏列唯一标识 field,即 window.localStorage.getItem(tid+"BsTable")
再通过 Bs.Table 的 hideColumn 方法或触发 标签 "click" 事件循环隐藏列。

保存配置:
在用户离开页面或者配置显示、隐藏列时,通过 Bs.Table 的 getHiddenColumns 方法或遍历 Bs.Table 的 DOM,获取所有隐藏列的 field,存储在 LocalStorage 中,即 window.localStorage.setItem(tid+"BsTable",sConfig)

实现:
  • LocalStorage 相关
var oStorage = {
  _Storage: window.localStorage,
  isSupportStorage: function () {
    return this._Storage != undefined ? true : false;
  },
  hasItem: function (item) {
    return this._Storage.hasOwnProperty(item);
  },
  getItem: function (item) {
    return JSON.parse(this._Storage.getItem(item));
  },
  setItem: function (item,val) {
    return this._Storage.setItem(item,JSON.stringify(val));
  }
};
  • Bs.Table 配置 (建议使用第一种)
//1.使用触发标签click事件隐藏列
······
  showColumns: true, //enable show/hide columns menu
  onLoadSuccess: function () {
    //browser supported LocalStorage and has userConfig
    if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
      //get userConfig from LocalStorage
      var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
      aUserConfHideCols.forEach(function (sField) {
        $(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField 
+ ']').trigger("click");
      });      
    }    
  },
······
//2.使用BsTable hideColumn方法
//这个方法直接隐藏列,不会触发下拉框的"click"事件,下拉框里面列仍然为"显示"状态,需要再remove掉active类。
······
  showColumns: true, //enable show/hide columns menu
  onLoadSuccess: function () {
    //browser supported LocalStorage and has userConfig
    if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
      //get userConfig from LocalStorage
      var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
      aUserConfHideCols.forEach(function (sField) {
        $scope.$broadcast('hideColumn'+ '#' + tid, sField);
        $(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField 
+ ']').parent().removeClass("active");
      });      
    }    
  },
······
  • 保存 userConfig
//1.用户配置显示、隐藏列时保存userConfig
//1.1BsTable onColmunSwitch事件监听
······
  onColumnSwitch: function () {
    $scope.$broadcast('getHiddenColumns' + '#' + tid, function(aCols) {
      var aTmpConfig = [];
      aCols.forEach(function(col) {
        aTmpConfig.push(col.field);
      });
      oStorage.setItem(tid + "BsTable", aTmpConfig);
    });
  },
······
//1.2DOM 事件监听
$(".bootstrap-table ul.dropdown-menu li").on("click",function () {
  var aTmpConfig = [];
  $(".bootstrap-table ul.dropdown-menu").find("input").each(function (i,v) {
    if(!$(v).parent().hasClass("active")) {
      aTmpConfig.push($(v).attr("data-field"));
    }
  });
  oStorage.setItem(tid+"BsTable",aTmpConfig);
});
//2.在离开页面时保存userConfig
//这个无法实现,在'$destroy'的事件里,BsTable实例已经被销毁,getHiddenColumns方法没有正确的返回值。
//$scope.$on('$destroy',function() {
//  $scope.$broadcast('getHiddenColumns'+ '#' + tid, function (aCols) {
//    var aTmpConfig = [];
//    aCols.forEach(function (col) {
//      aTmpConfig.push(col.field);
//    });
//    oStorage.setItem(tid+"BsTable",aTmpConfig);
//  });
//});

Finally. 根据项目环境,选择方案如下:

var tid = *****; //项目中BsTable的唯一标识id
var oStorage = {
  _Storage: window.localStorage,
  isSupportStorage: function () {
    return this._Storage != undefined ? true : false;
  },
  hasItem: function (item) {
    return this._Storage.hasOwnProperty(item);
  },
  getItem: function (item) {
    return JSON.parse(this._Storage.getItem(item));
  },
  setItem: function (item,val) {
    return this._Storage.setItem(item,JSON.stringify(val));
  }
};
······//此处省略BsTable其他配置BsTableOpt
var uConfigOpt = {
  showColumns: true, //enable show/hide columns menu
  onLoadSuccess: function () {
    //browser supported LocalStorage and has userConfig
    if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
      //get userConfig from LocalStorage
      var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
      aUserConfHideCols.forEach(function (sField) {
        $(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField 
+ ']').trigger("click");
      });      
    }    
  },
  onColumnSwitch: function () {
    $scope.$broadcast('getHiddenColumns' + '#' + tid, function(aCols) {
      var aTmpConfig = [];
      aCols.forEach(function(col) {
        aTmpConfig.push(col.field);
      });
      oStorage.setItem(tid + "BsTable", aTmpConfig);
    });
  }
}
$.extend(true,BsTableOpt,uConfigOpt);

--- 上述实现没有体现区分用户设置:即在同一 pc 上,由不同的用户访问该表格,对自定义列的配置是一样婶儿的,所以建议在保存 storage 时,key 值增加 userName 信息。---



作者:何学斌
链接:https://www.jianshu.com/p/f59babb519ba
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



你可能感兴趣的:(BootstrapTable 自定义列本地存储实践)