我正在开发一个包含多页表单的SPA。在重新加载时丢失表单状态是一个非常糟糕的UX。特别是因为表单相当大。
由于这是一个SPA,浏览器在重新加载后将无法恢复表单状态。即使可以,它也是一个多页表单,其中只显示字段的子集(尽管它可能会填充隐藏的输入,正如我所想到的)。
我本来可以使用历史状态来存储当前表单状态,但我希望“后退”按钮能够返回到上一个表单页面,而不清除当前页面上的进度。
我本来可以使用sessionStorage,但是我需要将文件和图像作为表单的一部分来存储。+它是同步的。
我本可以将状态与服务器同步,但我不想在后端引入如此复杂的问题,尤其是感觉这个问题可以在客户端上完全解决。
我在考虑使用IndexedDB。但是当表单状态不可访问并且需要清除时(例如,由于用户关闭选项卡),问题就出现了。
我可以想到的解决方法之一是通过service worker,因为它拥有所有当前打开的选项卡的列表(通过self.clients.matchAll()
API),并定期对与现在丢失的客户端ID相关的数据进行垃圾收集。
不幸的是,这是一个相当复杂的跳跃,以引入一个适当的服务工人支持的应用程序。我宁愿推迟服务工人的引入,直到我将被要求实现离线第一支持。
我想知道,如果有不同的解决方案来解决SPA中的表单持久性问题,那将需要更少的开发资源来引入。
2条答案
按热度按时间jaql4c8m1#
我假设您已经在关于Page Lifecycle API的博客文章中看到了“如果我不能在冻结或终止状态下运行异步API,我如何将数据保存到IndexedDB?”指南,因为使用服务工作者来持久化数据是其中列出的选项之一。
另一种选择是在
IDBTransaction
对象上使用commit()
method,以便在关闭选项卡时执行有效的同步只写IDB操作。本文提到commit()
在当时并没有得到广泛支持,但自从最初编写以来,浏览器支持已经得到了实质性的改进。gab6jxml2#
我想了无数种方法来使用这种东西,但都没有用。
pagehide
、beforeunload
和unload
的触发不够可靠(尤其是在移动的上)。clients.matchAll()
不返回丢弃的客户端(在移动的上大量存在),这意味着它们的会话仍然可以恢复,而我的服务工作人员会认为它们永远消失了(并从状态中进行垃圾收集)。我可能会对表单状态采取基于时间的(或LRU)逐出策略。或者定期检查未使用的条目,例如,一年左右,或者当我运行接近提供的配额时-触发LRU逐出。
理想情况下,通过会话作用域的IndexedDB示例可以很容易地解决这个问题。我记得在Web平台上有Jake Archibald mentioned he wants something like this。我认为这应该是一个很好的补充,老实说,在Web开发社区中讨论这个问题的人并不多(因为我不能通过谷歌搜索找到我的问题的答案(也不能讨论))。我真的认为我们应该努力以这样的方式改善UX。也许我应该再给杰克一点时间,让他(和网络工作组)知道确实需要它,而且......谁知道呢......也许有一天我们会看到它的实现。
至于现在,这是一个不幸的未解决的问题,因为我仍然不是100%满意的时间为基础的驱逐。