我有一个由DataTables 1.10驱动的表。过滤已打开。当我谈论"做一个搜索"下面,我正在讨论使用此表的过滤功能。
关闭stateSave
,一切正常。但是,当stateSave
打开时,会发生以下情况:
Alice以管理员身份登录。因为管理员拥有所有权限,所以当她搜索文章时,她可以看到所有文章。由于某些文章已发布且某些文章未发布,因此该表格中有一列显示哪些文章已发布,哪些文章未发布。到目前为止一切顺利。
随机用户Bob访问该网站。随机用户无法看到未发布的文章,因此该表隐藏了显示发布状态的列。到目前为止一切顺利。
Alice退出。她现在像一个随机用户访问该网站。所以她应该看到Bob看到的确切内容。但是,当她进行搜索时,仍然会看到指示发布状态的列。
(注意:我在这里讨论的问题纯粹是用户界面之一。服务器确保无特权用户无法获得未发布文章的记录。但问题是附加列为非特权用户提供了他们不需要的信息。他们只能在搜索中看到发布的文章,因此他们不需要看到他们在搜索中获得的每篇文章都已发布。)
配置数据表的代码通过执行以下操作来隐藏发布列:
var columnDefs = [];
if (!privileged) {
columnDefs.push({
targets: [1],
orderable: false,
visible: false
});
}
columnDefs
作为columnDefs
选项传递给DataTable。
问题是DataTables将列可见性等内容存储到它保存到localStorage
的状态中。因此,当Alice注销并再次作为非特权用户进行搜索时,即使columnDefs
的值正确,也会被保存状态覆盖。当Alice是管理员时,该状态被存储,并且它声明了发布列是可见的,因此即使Alice以非特权用户身份访问该站点,它仍然可见。
我想要的是让用户从保存状态中受益,但避免在用户权限发生变化时保持此状态。
注意事项:
我不想使用sessionStorage
,因为我希望状态在浏览器关闭之间保持不变,但在浏览器关闭时会清除sessionStorage
。
我不能使用服务器分配的会话cookie来检测登录和注销,因为它只是HTTP。此外,特权可能因其他原因而改变。
我不想在保存状态下任意设置过期时间。
答案 0 :(得分:8)
我已经确定的解决方案是在保存的数据中使用其他字段来了解我关心的条件何时发生了变化。这是一个字段,其值会根据用户当前所拥有的权限而更改。例如,因为在我这里描述的情况下,我决定隐藏或显示一个名为priviledged
的变量(根据服务器提供的数据初始化)的列,它可以很简单:
var token = privileged;
然后我设置stateSaveParams
以在保存状态时记录令牌:
stateSaveParams: function (settings, data) {
data.myapp_token = token;
}
前缀myapp_
就是为了避免与DataTable自己的字段发生可能的冲突。
我设置了stateLoadParams
,以便如果token
的当前值与之前记录的值不同,则清除状态:
stateLoadParams: function (settings, data) {
if (data.myapp_token !== token) {
this.api().state.clear(); // Clears the state.
return false; // Tells DataTables to not use the state that was stored.
}
// This return is here to keep the IDE happy but does not do anything special.
return undefined;
},
我只是将token
设置为我在我的问题(privileged
)中显示的单一条件,但在生产中我使用变量和本地的组合版本号,所以如果我做了一些需要清除状态但不能被检测为特权更改的东西,我可以根据需要提高令牌的值。