序列化是保存工作区的状态,以便稍后将其重新加载到工作区。这包括序列化您要保存的任何块、变量或插件状态。您可以将需要保存的所有数据转换为基于文本的格式以便于存储,之后再将这些数据加载到功能齐全的工作区中。
Blockly 为此类数据提供了两种格式:JSON 和 XML。我们建议为新项目使用 JSON 系统,并鼓励使用 XML 的旧项目进行升级。XML 系统是旧版保存格式。我们不会移除该版本,但不会为其添加新功能。
JSON 系统
JSON 序列化系统由多个序列化器组成。块和变量有内置序列化器,您还可以注册其他序列化器。每个序列化器都负责序列化和反序列化特定插件或系统的状态。
保存和加载
工作区
您可以对 workspaces
命名空间调用 save
和 load
方法,对整个工作区的状态进行序列化或反序列化。
const state = Blockly.serialization.workspaces.save(myWorkspace);
Blockly.serialization.workspaces.load(state, myWorkspace);
这些调用会对在工作区中注册的所有单个系统(由序列化器表示)进行序列化或反序列化。
单个分块
您可以通过对 blocks
命名空间调用 save
和 append
方法,对各个块进行序列化或反序列化。
const blockJson = Blockly.serialization.blocks.save(myBlock);
const duplicateBlock =
Blockly.serialization.blocks.append(blockJson, myWorkspace);
单个系统
您可以通过构建关联的序列化程序并调用其 save
和 load
方法,对各个系统(例如块、变量、插件等)进行序列化或反序列化。
// Saves only the variables information for the workspace.
const serializer = new Blockly.serialization.variables.VariableSerializer();
const state = serializer.save(myWorkspace);
serializer.load(state, myWorkspace);
反序列化顺序
JSON 系统具有明确的反序列化顺序,这可以更轻松地防止在保存过程中出现重复的状态。
调用 Blockly.serialization.workspaces.load
时,系统会按优先级为序列化程序提供要反序列化的数据状态。序列化器部分对此进行了进一步说明,其目的是允许序列化器依赖于其他系统的状态。
对内置序列化程序进行反序列化的顺序如下:
- 变量模型会进行反序列化。
- 过程模型已反序列化。
- 代码块会反序列化。各个顶级块会按任意顺序进行反序列化。
- 类型已反序列化。这会构建块、触发其 init 方法,并混入扩展程序。
- 属性会进行反序列化。这包括可应用于任何块的属性。例如:x、y、collapsed、disabled 和 data。
- 额外状态会反序列化。如需了解详情,请参阅扩展程序和修饰符文档。
- 代码块已连接到其父级(如果有)。
- 图标已进行反序列化。各个图标会以任意顺序进行反序列化。
- 字段会进行反序列化。各个字段会以任意顺序进行反序列化。
- 输入块会反序列化。这包括连接到值输入和语句输入的代码块。各个输入会以任意顺序进行反序列化。
- 后续块会反序列化。
何时保存额外状态
对于块,如果顺序中较低的内容依赖于较高顺序的内容,则应复制该数据并将其添加到额外状态中。
例如,如果您的字段仅在下一个块连接时才存在,则应将有关下一个块的信息添加到 extra 状态中,以便在字段的状态被反序列化之前将其添加到块中。
不过,如果某个输入仅在字段具有特定值时才存在,则无需将与该字段相关的信息添加到额外状态中。这是因为字段的状态会先反序列化,如果是,您就可以将输入添加到块中。通常,添加输入将由验证器触发。
请注意,关于重复状态的规则还应考虑到,块堆栈、图标、字段和输入块以任意顺序进行反序列化。例如,如果有一个字段 B 仅在另一个字段 A 具有特定值时才存在,那么您应将与 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
,用于确定反序列化顺序。您可以根据内置优先级设置序列化程序的优先级
调用 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
函数。这可确保在加载更多状态之前,插件/系统的状态是干净的。例如,工作区评论序列化器会从工作区中移除所有现有评论。 - 系统会调用提供的
load
函数。
XML 系统
借助 XML 系统,您可以将工作区序列化为 XML 节点。这是 Blockly 的原始序列化系统。该 SDK 现已被搁置,这意味着它不会再收到新功能。因此,我们建议您尽可能使用 JSON 系统。
API
如需了解 XML 系统的 API,请参阅参考文档。
块钩子
如需了解如何向块添加额外的序列化,请参阅扩展程序和修饰符文档。
字段钩子
如需了解如何对字段进行序列化,请参阅自定义字段文档。
在 JSON 和 XML 之间进行选择
我们建议使用 JSON 序列化器而不是 XML。JSON 系统允许您将工作区的状态序列化为 JavaScript 对象。这样做有以下好处:
- JSON 易于压缩或转换为其他格式。
- JSON 易于以编程方式处理。
- JSON 易于扩展和附加数据。
此外,XML 系统将不再收到更新,并且与 JSON 序列化器相比,它已经缺少一些功能。例如,您可以注册自己的 JSON 序列化器,以便轻松保存和加载其他数据,例如您添加的插件或自定义项的数据。在 XML 系统中无法实现此操作。
如果您之前使用的是 XML 序列化,请参阅迁移指南,了解如何升级。