这是一个
stateSaveOption
参数引发的一系列“惨案”。
为什么说又爱又恨?这要从很久很久以前说起……
目录
-
爱在哪里?
说实在的stateSave
这个还是 DataTables 一个比较好的功能,保存上次分页状态,数据上次排列顺序,上次条件过滤的结果……,
这些对于某些开发者来说无疑是非常棒的,所以能不爱吗?无法抗拒啊
1
2
3
4
5
$(document).ready(function() {
var t = $('#example').DataTable({
"stateSave": true
});
});
在初始化的时候如上述代码,即可打开本地状态保存的功能。
-
恨在哪里?
正是因为他功能如此之强大,导致了其他“灵异事件”。
- 怎么刷新了还是之前的结果?
- 为什么我的过滤条件不起作用?
- 这个排序怎么没效果?
- ……
类似的问题有很多,看到这样的问题我第一眼需要看的就是你代码里有没有加这个参数,如果你无意间加了这个参数,那么问题很简单,按照以下两步走:
- 第一:去掉
stateSave
或者值赋值为false
- 第二:清空本地缓存
这样操作后,上面提到的问题就能解决。一般来说超过99%的类似问题都是因为不理解stateSave
参数导致的。
从上面这些也反应了一个问题:
知其然不知其所以然,大家确实查询了资料、看了文档,但是只是照搬,没有弄清楚真正的意思,这样肯定会给自己带来不少麻烦。
这里告诉大家一个技巧,一般插件都有默认值、无参数的初始化方法,这是最基本的需求,而不是自己还要去加这样或那样的参数。比如如下代码:
1
2
3
$(document).ready(function() {
var t = $('#example').DataTable();
});
只要这样,DataTables 就可以渲染你的表格,给你的表格加上分页,排序,过滤。你如果还需要其他功能,通过查询文档再相应加上相关的属性。 我极力推荐这种做法,一是自己的代码很简洁,二是不会给自己添麻烦,三是遇到问题后,代码贴出去问题也能很快的被解决。
PS:我推荐大家把 DataTables参数配置模板 仔细看一遍,这样对DT的参数有个整体的把握,用起来会更得心应手
-
什么时候该使用这个参数?
知其然,还得知其所以然。弄清你需要到达什么样的目的,你就会去使用他。不过在使用之前,你得知道 stateSave
是什么意思?
很简单,你可以简单理解为缓存。他可以缓存DT的所有状态。
比如说有以下应用:
- 保持翻页,比如当前翻到第4页,下次再打开的时候任然是第4页
- 保持排列顺序,比如第二列是降序排列,下次再打开第二列仍是降序排列
- 保持过滤条件,比如前一次输入的过滤条件是【DataTables中文网】,再次打开任然是按照此关键字来过滤数据
-
…… 当然不止我上面所提到的这些,大家可以天马行空,发挥自己的想象,没有做不到,只有想不到,做到做不到,试试就知道
-
示例讲解
下面通过具体的例子告诉大家 DT 究竟是怎么保存状态的
一个简单的例子演示了几个回调函数之间是怎么执行的,执行顺序如何?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
$("#example").DataTable({
//开启本地保存功能
stateSave: true,
//保存状态操作
"stateSaveParams": function (settings, data) {
console.log("stateSaveParams");
//这里可以操作保存的数据,写上自己特定的逻辑
//data.search.search = "";
},
"stateSaveCallback": function (settings, data) {
console.log("stateSaveCallback");
//DT默认保存的key值为DataTables_+表格id+页面名称
localStorage.setItem('DataTables_' + settings.sInstance, JSON.stringify(data));
// 你可以把这些数据保存在服务器上,上面的代码标识使用本地储存来存储这些数据
/**$.ajax( {
"url": "/state_save",
"data": data,
"dataType": "json",
"type": "POST",
"success": function () {}
} );
**/
},
//读取状态操作
"stateLoadParams": function (settings, data) {
console.log("stateSaveParams");
//在读取数据的时候可以改变数据,根据自己逻辑来处理
//data.search.search = "";
//或者你可以直接禁用从缓存里读取数据,只要直接返回false即可
//return false;
},
"stateLoadCallback": function (settings) {
console.log("stateLoadCallback");
return JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance));
//同样你还可以从服务器取数,采用同步的方式获取到保存在服务器里的数据
/**var o;
$.ajax( {
"url": "/state_load",
"async": false,
"dataType": "json",
"success": function (json) {
o = json;
}
} );
return o;**/
},
//状态加载完后执行的回调函数
"stateLoaded": function (settings, data) {
console.log("stateLoaded");
//在这里你可以打印出保存的缓存数据
//alert( 'Saved filter was: '+data.search.search );
},
"ajax": {
"url": "/objects.txt"
},
"columns": [
{"data": "name"},
{"data": "position"},
{"data": "salary"},
{"data": "start_date"},
{"data": "office"},
{"data": "extn"}
],
"language": {
"lengthMenu": "每页_MENU_ 条记录",
"zeroRecords": "没有找到记录",
"info": "第 _PAGE_ 页 ( 总共 _PAGES_ 页 )",
"infoEmpty": "无记录",
"search": "搜索:",
"infoFiltered": "(从 _MAX_ 条记录过滤)",
"paginate": {
"previous": "上一页",
"next": "下一页"
}
},
"dom": "<'row'<'col-xs-2'l><'#mytool.col-xs-4'><'col-xs-6'f>r>" +
"t" +
"<'row'<'col-xs-6'i><'col-xs-6'p>>"
});
执行顺序如下:
保存
stateSaveParams
stateSaveCallback
读取
stateLoadParams
stateLoadCallback
stateLoaded
PS:如果对此还有疑问的,大家可以clone下面提到的完整工程,自己试验最终的结果
下面的 JSON 数据为 DT 定义的格式,按照此要求来存储和读取表格的状态,达到缓存的效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"time": {number} // 时间戳,状态创创建、修改的时间
"start": {number} // 显示起始位置
"length": {number} // 每页显示的条数
"order": {array} // 二维数组,用来描述那些列按照什么要求排序
"search": {
"search": {string} // 搜索条件
"regex": {boolean} // 是否支持正则表达式
"smart": {boolean} // 是否开启了智能搜索
"caseInsensitive": {boolean} // 不区分大小写
},
"columns" [
{
"visible": {boolean} // 列是否隐藏显示
"search": { // 包含每列的单独搜索条件,格式和上面的一致
"search": {string} // 搜索条件
"regex": {boolean} // 是否支持正则表达式
"smart": {boolean} // 是否开启了智能搜索
"caseInsensitive": {boolean} // 不区分大小写
}
},
……
]
}
再贴上一个实例的真实数据样例,完整的工程点我
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
"time": 1475739393071,
"start": 0,
"length": 10,
"order": [
[
5,
"asc"
]
],
"search": {
"search": "Developer",
"smart": true,
"regex": false,
"caseInsensitive": true
},
"columns": [
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
},
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
},
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
},
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
},
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
},
{
"visible": true,
"search": {
"search": "",
"smart": true,
"regex": false,
"caseInsensitive": true
}
}
]
}
上面的数据表示当你下次重新刷新页面后,表格将显示如下描述所示:
- 从第一条数据显示,每页显示10条数据
- 第6列升序排列
- 全局过滤条件为”Developer”,不支持正则,支持智能搜索,区分大小写
- 六列都显示,没有单独的过滤条件
PS:在实际操作过程中,如果是多列同时排序 order
保存的数据如下:[[5,"asc",0],[4,"desc",0]]
, 由于作者没有文档说明第三个
数字代表什么,我猜测这是用来确定排序优先级的参数,具体大家可以查看源码,作者是怎么解析第三个数字的
-
总结
说了这么多,大家可能终于明白了 stateSave
究竟是什么意思了。看完了这篇文章,大家同意这篇文章的标题里说的【又爱又恨】吗?