【问题标题】:Is it possible to serialize/deserialize dojo widget objects?是否可以序列化/反序列化 dojo 小部件对象?
【发布时间】:2011-02-24 19:50:40
【问题描述】:

有人知道是否可以将 dojo 小部件 (dijit) 对象序列化/反序列化为字符串或可以跨浏览器会话持久化的某种表示形式?

我的场景: 我有一个包含各种 dijit 的网页,我希望能够拍摄“快照”并在新的浏览器会话中恢复,以便将所有内容恢复到完全相同的状态。 为了做到这一点,我相信我需要序列化/恢复页面的 DOM 树以及 dijit 对象。我已经能够序列化 DOM 树,目前正在通过替换页面 HTML 节点的内容来恢复它。恢复页面的 DOM 后,所有 dijit 都不起作用 - 它们被正确呈现,但您无法单击其中任何一个。我相信这是因为当页面第一次加载时,dojo 解析器已经通过 DOM 运行,并且替换整个 HTML DOM 元素会破坏该页面的 dijit 注册表中的所有 dijit。这意味着必须重新设置 dijit 类实例化。

理想情况下,当我拍摄“快照”时,将页面的 dijit.registry 中包含的每个 dijit 对象序列化为文件,并在会话恢复时,重新构造这些 dijit 对象并将它们添加回 dijit 注册表。

类似: dijit.registry.forEach(函数(小部件){ // 保存小部件对象,以便可以在新的浏览器实例中恢复它? });

有没有人尝试过或者知道是否可以不编写自定义序列化程序?

【问题讨论】:

    标签: javascript dojo


    【解决方案1】:

    我不确定我是否同意您使用的技术。更好的方案是简单地序列化每个 dijit 的数据状态。我知道这会做更多的工作,但您正试图保留数据的状态,带上 UI 似乎保留了不必要的信息。

    话虽如此,dojo 解析器的调用可以独立于页面加载。你要找的是

    dojo.parser.parse();
    

    在重新填充 innerHTML 后运行它应该重新解析并重新创建 dijits 请参阅此页面以获取完整参考:http://docs.dojocampus.org/dojo/parser

    【讨论】:

    • 这里是我将要实施您建议的解决方案的过程: 1) 不是序列化整个 dijit 对象,而是仅序列化恢复 dijit 状态所需的属性。 (跳过函数和循环引用) 2) 重新填充 DOM 树时,运行 dojo.parser.parse() 重新实例化所有 dijit。 3) 反序列化dijit信息并为每个dijit - 确定类型 - 根据类型,调用dijit上的方法恢复其状态(只能通过方法调用修改dijit的状态)
    • 第 2 步让我担心:当解析器重新解析页面时,它会修改每个 dijit 附加到的 DOM 元素的属性吗? (因为 dijit 被重新实例化为“新”状态)第 3 步将很难实施。我需要根据 dijit 类型和特定的属性名称来确定需要调用的方法。例如,如果小部件是 dijit.form.textbox 并且属性是 {value: "First Name"} 我需要获取这两条信息并决定调用 dijit.form.textbox.set('displayedValue ', '名字')
    【解决方案2】:

    任何 javascript 对象(包括 dojo 小部件)都可以使用 dojo.toJson() 序列化为 JSON,例如:

    var deserialisedValue = dojo.toJson(myObject);
    

    【讨论】:

    • dijit.registry.forEach(function(w){ console.log(dojo.toJson(w)); });引发“无法序列化 DOM 节点”异常
    • 即使这确实有效,您如何建议反序列化它?见:stackoverflow.com/questions/22945894/…
    【解决方案3】:

    我的猜测是,我们可以序列化和反序列化 dojo 小部件,但是构建这些小部件的商店(以及商店的类型)也应该序列化和反序列化。 这可能涉及使用 eval 语句,这被认为是邪恶的。另外我认为这些小部件订阅的事件处理程序、主题可能不会被序列化和反序列化。

    【讨论】:

      【解决方案4】:

      如果收件人页面(dijit 将被反序列化)具有相同数量的小部件,最简单的解决方案是将所有内容包装在 dijit/form/Form 中,并调用 valueJSON = form.get('value') 进行序列化,并调用 form.set('value', valueJSON) 进行反序列化。

      对于 dgrid 和图表等表单内部的小部件,它变得更加棘手。您将不得不采用特定于小部件的方法。例如:您可以通过调用 grid.save() 然后调用 JSON.stringify (grid.get('store')) 轻松序列化值已更改的 dgrid。

      如果反序列化页面可以有任意数量的小部件,我同意@treaint 你可以通过widget.get('declaredClass') \\Returns TextBox etc. 获取小部件的类型

      我们遇到了类似的问题,但我们使用表单的 get/set 值很容易地解决了它!它非常巧妙,它遍历所有子节点,对每个子节点调用 child.get('value'),并将其与自己的值混合。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        • 1970-01-01
        • 2015-06-06
        • 1970-01-01
        • 2021-12-08
        相关资源
        最近更新 更多