2012 年 1 月 16 日星期一

使用 localStorage 保存状态

更新:默认情况下,DataTables 1.10 使用 localStorage 存储状态。保留此帖子供参考;有关如何使用 DataTables 的最新说明,请参阅 手册

编写软件库时遇到的最大挑战之一是维护其 API,并确保升级到该库的较新版本尽可能地无痛。DataTables API 经受住了时间的考验,但时不时地,会出现一些之前已实现但未来版本中却不希望出现的内容。在本例中,DataTables 1.9(测试版 2)变更了其状态存储方式,并移除两个旧的初始化选项,取而代之的是更灵活的选项。

在本帖子中,我将解释更改的方面、DataTables 1.9 的新功能,并演示如何使用这些改进内容以便非常容易地为表格实现状态存储,所使用的存储方式不是 cookie,而是 localStorage,或者你希望使用的任何其他状态存储。

状态存储

DataTables 中的状态存储通过将 JSON 字符串存储到 cookie 中来完成,以便在保持尽可能多的浏览器兼容性的同时,在客户端存储状态。有时,能够修改表格保存的参数(添加你自己的参数或修改核心参数)很有用,而 DataTables 1.8 通过两个初始化选项提供了此选项

然而,使用这些选项实际上与直觉相去甚远,现在它们已被五个新的初始化选项取代,这些选项清晰地分离了实际保存和加载数据(fnStateSavefnStateLoad)的操作、定义和修改要保存和加载的参数(fnStateSaveParamsfnStateLoadParams),以及状态已加载时的通知(fnStateLoaded)。

传递给每个函数的参数在以上链接的文档中进行了详细定义。这些新函数的一个主要优势是它们将提供一个 Javascript 对象让你使用,而不是以前必须进行处理的字符串,这在很大程度上简化了操作!fnStateSavefnStateLoad 的默认操作仍然是使用内部 cookie 保存代码,但正如你将在下面看到的那样,你可以轻松更改这个设置,以保存你希望保存的状态。

不要更改 API!

在不提前一个主要版本淘汰更改的 API 的情况下移除 API 是一种例外情况,这并不是 DataTables 项目通常采用的做法,但在这种情况下,状态保存 API 糟糕透顶,因为它很难使用,并且正是因为这个事实而很少被使用。因此,我觉得采取这一步是正确的 - 如果有人当前正在使用 fnStateLoadCallbackfnStateSaveCallback 初始化选项,并希望更新到 1.9,请将你当前的代码发布到 论坛,我将提供免费支持,以使用新方法更新代码。

localStorage

Cookie 有一些缺点,例如需要增加 HTTP 带宽,并且有 4K 的限制。W3C Web 存储规范中定义 localStorage 为一种本地存储方法,我们可以将其用于 DataTables,以在不使用 cookie 的情况下存储状态。

为了将状态保存与 localStorage 结合使用,我们首先必须使用 bStateSave 初始化选项启用状态保存,然后定义我们的 fnStateSavefnStateLoad 函数。fnStateSave 将采用两个参数,第一个参数是 DataTables 设置对象,第二个参数是我们希望保存的状态对象。为了保存状态,我们只需使用 localStorage.setItemJSON.stringify(请注意,由于这个原因,这将无法在不支持 localStorage 或具有内置 JSON 解析能力的浏览器中工作)。然后我们可以将 fnStateLoad 定义为一个函数,这个函数将仅仅读取我们的已保存对象、解析 JSON 并将其返回。

$(document).ready(function() {
    $('#example').dataTable( {
        "bStateSave": true,
        "fnStateSave": function (oSettings, oData) {
            localStorage.setItem( 'DataTables', JSON.stringify(oData) );
        },
        "fnStateLoad": function (oSettings) {
            return JSON.parse( localStorage.getItem('DataTables') );
        }
    } );
} );

就这样完成!存储在 DataTables 中的设置的 localStorage 没有 cookie 的缺点。一个简单且有用的修改是考虑当前的网页 URL,以防你在你的域中使用了多个 DataTables,因为 localStorage 是域范围的。我们可以使用 window.location.pathname 来完成此操作。

$(document).ready(function() {
    $('#example').dataTable( {
        "bStateSave": true,
        "fnStateSave": function (oSettings, oData) {
            localStorage.setItem( 'DataTables_'+window.location.pathname, JSON.stringify(oData) );
        },
        "fnStateLoad": function (oSettings) {
            return JSON.parse( localStorage.getItem('DataTables_'+window.location.pathname) );
        }
    } );
} );

使用此方法,你可以轻松了解如何扩展此方法,以使用 Ajax 在服务器上的数据库中存储状态(如果你这样做,请注意 fnStateLoad Ajax 调用必须是同步的,因为未为异步请求提供回调)。

结论

<

总体而言,我希望你会同意,这是一个对旧的、模糊的和困难的状态保存 API 非常受欢迎的更新,我期待看到新的 API 将如何被使用,我希望你会喜欢使用 DataTables 1.9。

如果希望添加任何内容或有任何问题,可以在 论坛中获取此帖的评论和讨论