序列化

序列化會儲存工作區的狀態,方便日後載入工作區。這包括序列化您要儲存的任何區塊、變數或外掛程式的狀態。您可以將所有需要儲存的資料轉換為文字格式,方便儲存,然後稍後將這些資料載入功能完整的工作區。

Blockly 提供兩種格式供您使用:JSON 和 XML。我們建議您在新的專案中使用 JSON 系統,並鼓勵使用 XML 的舊專案進行升級。XML 系統是舊版儲存格式。不會移除,但不會再新增新功能。

JSON 系統

JSON 序列化系統由多個序列化器組成。系統內建區塊和變數的序列化器,您也可以註冊其他序列化器。每個序列化器都負責序列化和反序列化特定外掛程式或系統的狀態。

儲存及載入

工作區

您可以呼叫 workspaces 命名空間中的 saveload 方法,對整個工作區的狀態進行序列化或反序列化。

const state = Blockly.serialization.workspaces.save(myWorkspace);
Blockly.serialization.workspaces.load(state, myWorkspace);

這些呼叫會序列化或去序列化向工作區註冊的「所有」個別系統 (以序列化程式表示)。

個別區塊

您可以在 blocks 命名空間上呼叫 saveappend 方法,藉此序列化或反序列化個別區塊。

const blockJson = Blockly.serialization.blocks.save(myBlock);
const duplicateBlock =
    Blockly.serialization.blocks.append(blockJson, myWorkspace);

個別系統

您可以建構相關聯的序列化程式,並呼叫其 saveload 方法,將個別系統 (例如區塊、變數、外掛程式等) 序列化或去序列化。

// 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 時,序列化器會依優先順序提供狀態,以便以序列化方式還原。請參閱「序列化器」一節,進一步瞭解這項功能。這項功能的目的,是讓序列化器依賴其他系統的狀態。

內建序列化器的反序列化順序如下:

  1. 變數模型會經過反序列化。
  2. 程序模型會經過序列化。
  3. 區塊會經過反序列化。個別頂層區塊會以任意順序反序列化。
    1. 類型為反序列化。這會建構區塊、觸發其初始化方法,並混合擴充功能。
    2. 屬性會去序列化。包括可套用於任何區塊的屬性。例如:x、y、已摺疊、已停用和資料。
    3. 額外狀態會去序列化。詳情請參閱「擴充功能和變異器」說明文件。
    4. 區塊會連結至其父項 (如果有的話)。
    5. 圖示會去序列化。個別圖示會以任意順序進行反序列化。
    6. 欄位會經過反序列化。個別欄位會按任意順序反序列化。
    7. 輸入區塊會經過反序列化。包括與值輸入和陳述式輸入相關聯的區塊。個別輸入內容會以任意順序進行反序列化。
    8. 下一個區塊會經過反序列化。

儲存額外狀態的時機

就區塊而言,如果順序中較低的項目依附於較高的項目,您應複製該資料,並將其新增至額外狀態。

舉例來說,如果某個欄位只在下一個區塊連線時才存在,您應在額外狀態中新增該下一個區塊的相關資訊,這樣在欄位狀態經過反序列化前,就能將該欄位新增至區塊。

不過,如果您只有在欄位具有特定值時才會出現輸入內容,就不需要在額外狀態中加入該欄位的相關資訊。這是因為欄位的狀態會先經過反序列化,之後您就可以將輸入內容加入區塊。通常,新增輸入內容會由驗證器觸發。

請注意,複製狀態的規則也應考量到區塊堆疊、圖示、欄位和輸入區塊會以任意順序進行反序列化。舉例來說,如果您有一個欄位 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 時,系統會依優先順序觸發每個序列化器。優先順序值較高的序列化程式會在優先順序值較低的序列化程式之前觸發。

觸發序列化器時,會發生下列兩種情況:

  1. 系統會呼叫提供的 clear 函式。這可確保在載入更多狀態之前,外掛程式/系統的狀態是乾淨的。舉例來說,工作區留言序列化程式會從工作區移除所有現有的留言。
  2. 系統會呼叫所提供的 load 函式。

XML 系統

XML 系統可讓您將工作區序列化為 XML 節點。這是 Blockly 的原始序列化系統。此版本已進入凍結狀態,也就是說不會再新增任何新功能。因此,建議盡可能使用 JSON 系統。

API

如要瞭解 XML 系統的 API,請參閱參考說明文件

封鎖掛鉤

如要進一步瞭解如何在區塊中新增額外的序列化,請參閱「擴充功能和變數轉換器」說明文件。

欄位掛鉤

如要瞭解如何序列化欄位,請參閱「自訂欄位」說明文件。

選擇 JSON 或 XML

建議您使用 JSON 序列化程式,而非 XML。JSON 系統可讓您將工作區狀態序列化為 JavaScript 物件。這麼做有助於:

  1. JSON 很容易壓縮或轉換為其他格式。
  2. JSON 很容易以程式輔助方式處理。
  3. JSON 很容易擴充及附加資料。

此外,XML 系統將不再接收更新,而且相較於 JSON 序列化器,它已經缺少許多功能。舉例來說,您可以註冊自己的 JSON 序列化器,輕鬆儲存及載入其他資料,例如您新增的外掛程式或自訂項目的資料。但 XML 系統無法做到這一點。

如果您先前使用 XML 序列化,請參閱遷移指南,瞭解如何升級。