# 序列化
序列化操作会保存工作区的状态,以便稍后将其重新加载到工作区。这包括将要保存的所有代码块、变量或插件的状态序列化。您可以将需要保存的所有数据转换为基于文本的格式,以方便存储,之后再将该数据加载回功能齐全的工作区。
Blockly 为这种数据提供了两种格式:JSON 和 XML。我们建议您为新项目使用 JSON 系统,并鼓励使用 XML 的旧版项目进行升级。XML 系统是旧版保存格式。该版本不会移除,但不会获得新功能。
# JSON 系统
提示
注意:如需了解如何从 XML 迁移到 JSON,请参阅 迁移指南 (opens new window)。
JSON 序列化系统由多个序列化器组成。其中提供了块和变量的内置序列化器,您还可以注册其他序列化器。每个序列化器负责对特定插件或系统的状态进行序列化和反序列化。
# APIs
您需要的基本调用包括 Blockly.serialization.workspaces.save(workspace)
(用于保存工作区状态)和 Blockly.serialization.workspaces.load(stateToLoad, workspace)
(用于将已保存的状态加载到工作区中)。
需详细了解 JSON 序列化器 API,请参阅 参考文档 (opens new window)。您还可以序列化单个 块 (opens new window)。
# 反序列化顺序
JSON 系统具有明确的反序列化顺序,可让您更轻松地防止在保存过程中出现重复状态。
调用 Blockly.serialization.workspaces.load
时,系统会按照_优先级_为序列化器提供状态来反序列化。序列化器 部分对此做了进一步说明,其目的是允许序列化器依赖于来自其他系统的状态。
内置序列化器的反序列化顺序如下:
变量反序列化。
块是反序列化的。 各个堆栈/顶级代码块按_任意顺序_进行反序列化。
a. 类型反序列化。 这会触发代码块的 init 方法、扩展程序混合等。
b. 属性是反序列化的。 这包括可以应用于任何块的属性。例如:x、y、已收起、已停用、数据等。
c. Extra 状态是反序列化的。 如需了解详情,请参阅 扩展程序和转变器 文档。
d. 代码块连接到其父项(如果存在)。
e. 图标是反序列化的。 各个图标按_任意顺序_进行反序列化。
f. 字段反序列化。 各个字段按_任意顺序_进行反序列化。
g. 输入块是反序列化的。 这包括连接到值输入和语句输入的块。各个输入按任意顺序进行反序列化。
h. 后续代码块会反序列化。
# 何时保存额外状态
对于代码块,如果您的某些项依赖于顺序中较高的项,则应复制该数据并将其添加到额外状态。
例如,如果您的某个字段仅在连接下一个代码块时存在,则应将有关下一个代码块的信息添加到额外状态,以便可以在该字段的状态反序列化之前将该代码添加到代码块中。
但是,如果您的输入仅在字段具有特定值时存在,您就无需将该字段的相关信息添加到额外状态。这是因为字段的状态会先被反序列化,如果是,您就可以将输入添加到代码块中。添加输入通常由 校验器 触发。
请注意,有关复制状态的规则还应考虑块堆栈、图标、字段和输入块按任意顺序反序列化。例如,如果您有一个字段 B,仅当另一个字段 A 具有特定值时,该字段 B 才存在,则应将有关 A 的信息添加到额外状态,以防 B 在 A 之前反序列化。
# 块钩子
如需了解如何向块添加额外的序列化内容,请参阅 扩展程序和变形器 文档。
# 字段钩子
如需了解如何对字段进行序列化,请参阅 自定义字段 文档。
# 序列化器钩子
通过 JSON 系统,您可以注册序列化器,以便对某些状态进行序列化和反序列化。Blockly 的内置序列化器负责序列化有关块和变量的信息,但如果您想序列化其他信息,则需要添加您自己的序列化器。例如,默认情况下,JSON 系统不会序列化工作区级注释。如果要将它们序列化,您需要注册额外的序列化器。
其他序列化器通常用于对插件的状态进行序列化和反序列化。
Blockly.serialization.registry.register(
'workspace-comments', // Name
{
save: saveFn, // Save function
load: loadFn, // Load function
clear: clearFn, // Clear function
priority: 10, // Priority
});
注册序列化器时,必须提供以下几项:
序列化器的名称,数据也将保存在此名称下。
用于对与序列化器关联的插件/系统的状态执行
save
的函数。用于对状态应用
clear
的函数。用于对状态应用
load
的函数。priority
,用于确定反序列化顺序。您可以根据内置优先级 (opens new window)来确定序列化器的优先级
调用 Blockly.serialization.workspaces.save
时,系统会调用每个序列化器的 save
函数,并将其数据添加到最终 JSON 输出中:
{
"blocks": { ... },
"workspaceComments": [ // Provided by workspace-comments serializer
{
"x": 239,
"y": 31,
"text": "Add 2 + 2"
},
// etc...
]
}
调用 Blockly.serialization.workspaces.load
时,系统会按优先级顺序触发每个序列化器。优先级值较高的序列化器先于优先级值较低的序列化器触发。
触发序列化器后,会发生以下两种情况:
- 系统会调用提供的
clear
函数。这样可以确保在加载更多状态之前,插件/系统的状态是干净的。例如,workspace-comments 序列化器会从工作区中移除所有现有注释。 - 系统会调用提供的
load
函数。
# XML 系统
借助 XML 系统,您可以将工作区序列化为 XML 节点。这是 Blockly 的原始序列化系统。它现在已进行了 Box,这意味着它将不再接收新功能。因此,我们建议您尽可能使用 JSON 系统。
提示
注意:如需了解如何迁移到 JSON,请参阅 迁移指南 (opens new window)。
# APIs
如需了解 XML 系统的 API,请参阅 参考文档 (opens new window)。
# 块钩子
如需了解如何向块添加额外的序列化内容,请参阅扩展程序和转变器文档。
# 字段钩子
如需了解如何对字段进行序列化,请参阅 自定义字段 文档。
# 在 JSON 和 XML 之间进行选择
我们建议使用 JSON 序列化器,而非 XML。通过 JSON 系统,您可以将工作区的状态序列化为 JavaScript 对象。这样做的好处在于:
- JSON 易于压缩或转换为其他格式。
- 通过编程方式,JSON 非常易于使用。
- JSON 可以轻松扩展和附加数据。
此外,XML 系统将不再接收更新,并且与 JSON 序列化器相比,它已经缺少功能。例如,您可以注册自己的 JSON 序列化器,以便轻松保存和加载其他数据,例如用于插件的数据或已添加的自定义数据。在 XML 系统中无法做到这一点。
如果您之前使用过 XML 序列化,请参阅 迁移指南 (opens new window),了解如何升级。