项目后台由于使用的是FastAdmin,默认使用bootstrap-table作为表格组件
项目开发已经很久了,生成了很多表格,客户有个需求《系统可否保存用户上次勾选的隐藏列,打开列表时默认隐藏上次已经勾选的》
可通过监听 column-switch.bs.table 事件确定用户显示及隐藏列,保存至后端
由于当时已经非常多表了,没有办法通过修改每个js表格列内的visible属性来控制显示隐藏,干脆通过FastAdmin封装的require-table.js入手,通过监听bootstrap-table的 post-body.bs.table来解决,起初的方案是遍历后台返回的隐藏列,通过hideColumn来处理,隐藏列数为1列-3列的情况下性能还好,但是隐藏列较多的情况下就会出现卡顿,查了下hideColumn的实现
BootstrapTable.prototype.hideColumn = function (field) {
this.toggleColumn(getFieldIndex(this.columns, field), false, true);
};
BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {
if (index === -1) {
return;
}
this.columns[index].visible = checked;
this.initHeader();
this.initSearch();
this.initPagination();
this.initBody();
if (this.options.showColumns) {
var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
if (needUpdate) {
$items.filter(sprintf('[value="%s"]', index)).prop('checked', checked);
}
if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
$items.filter(':checked').prop('disabled', true);
}
}
};
可以发现,每当隐藏一列的时候,会重新初始化头部,搜索,分页等等,若隐藏列较多的情况下,需要重复初始化很多次,导致DOM渲染非常耗时,出现卡顿情况
解决方案:
BootstrapTable.prototype.hideManyColumn = function (fieldArr) {
this.toggleManyColumn(fieldArr, false, true);
};
BootstrapTable.prototype.toggleManyColumn = function (fieldArr, checked, needUpdate) {
if (fieldArr.length > 0)
{
for (let i in fieldArr)
{
let index_ = getFieldIndex(this.columns, fieldArr[i])
if (index_ === -1)
{
continue;
}
this.columns[index_].visible = checked;
}
this.initHeader();
this.initSearch();
this.initPagination();
this.initBody();
if (this.options.showColumns)
{
for (let i in fieldArr)
{
let index_ = getFieldIndex(this.columns, fieldArr[i])
if (index_ === -1)
{
continue;
}
var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
if (needUpdate)
{
$items.filter(sprintf('[value="%s"]', index_)).prop('checked', checked);
}
if ($items.filter(':checked').length <= this.options.minimumCountColumns)
{
$items.filter(':checked').prop('disabled', true);
}
}
}
}
};
将所有应该设为visible的列设置完之后,再去初始化一次头部等信息,然后判断筛选input勾选问题
若通过 post-body.bs.table 事件操作隐藏列,需加个全局判断,因为初始化列后会重复调用 post-body.bs.table 事件,避免程序陷入死循环
后端开发,前端略水,仅提供参考方案!