JSON 和 JavaScript

Blockly 有兩種定義區塊的方式:使用鍵/值組合的 JSON 物件,以及呼叫 Blockly API 的 JavaScript 函式。建議使用 JSON 格式,因為這種格式可簡化本地化作業,且較易讀寫。不過,它無法用於直接定義進階功能,例如變異器或驗證器。這些擴充功能必須以 JavaScript 編寫,通常會以擴充功能的形式呈現。

使用 JSON 或 JavaScript

這個區塊:

`string_length` 區塊。

可在 JSON 或 JavaScript 中定義如下:

JSON

Blockly.common.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String"
    }
  ],
  "output": "Number",
  "colour": 160,
  "tooltip": "Returns number of letters in the provided text.",
  "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);

defineBlocksWithJsonArray 會使用 init 函式,將每個 JSON 物件轉換為區塊定義物件。並將這些物件儲存在 Blockly.Blocks 中。

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};

由於區塊定義物件會混合到區塊物件,因此關鍵字 this 會參照要建立的實際區塊。

這兩種方法都會將區塊定義物件儲存在 Blockly.Blocks 中,並使用區塊類型名稱 (string_length) 做為索引鍵。區塊定義物件具有單一方法 (init),用於定義區塊的形狀。

混合 JSON 和 JavaScript

JSON 格式主要用於定義區塊的外觀和感受。它無法直接定義某些功能,例如驗證器和修飾器,因此您必須定義函式。如要解決這個問題,請盡可能使用 JSON 定義區塊,並使用 JavaScript 處理其餘部分。

以下範例會使用 init 函式建立區塊定義,該函式會使用 jsonInit 載入 JSON 物件和 JavaScript API,以定義動態工具提示。

JavaScript

// Define the block structure in JSON.
var mathChangeJson = {
  "message0": "change %1 by %2",
  "args0": [
    {"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
    {"type": "input_value", "name": "DELTA", "check": "Number"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 230
};

Blockly.Blocks['math_change'] = {
  init: function() {
    // Use jsonInit to load the JSON block structure.
    this.jsonInit(mathChangeJson);

    // Use JavaScript to define a tooltip function.
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return 'Add a number to variable "%1".'.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  }
};

區塊定義 API

本節將概述用於定義自訂區塊的物件和函式。

Blockly.Blocks

Blockly.Blocks 是儲存區塊定義的物件。其鍵為區塊類型名稱,值則為區塊定義物件。使用 JavaScript 定義區塊時,請使用 Blockly.Blocks

Blockly.Blocks['my_block'] = {
  init: function() {/* ... */},
  onchange: function() {/* ... */},
  // ...
}

常見的錯誤是假設 Blockly.Blocks 會儲存區塊,並嘗試以下操作:這會失敗,因為 Blockly.Blocks 儲存的是區塊定義,而非區塊。

// Fails with "Blockly.Blocks.my_block.setColour is not a function".
Blockly.Blocks['my_block'].setColour(150);

defineBlocksWithJsonArray

defineBlocksWithJsonArray 會接受 JSON 物件陣列,並根據這些物件建立區塊定義,然後將這些定義新增至 Blockly.Blocks

Blockly.common.defineBlocksWithJsonArray([
  {
    type: 'my_block1',
    // ...
  }
  {
    type: 'my_block3',
    // ...
  }
  {
    type: 'my_block2',
    // ...
  }
]);

createBlockDefinitionsFromJsonArray 和 defineBlocks

createBlockDefinitionsFromJsonArray 會接受 JSON 物件的陣列,並傳回將區塊類型名稱對應至區塊定義的物件。這個方法通常會與 defineBlocks 搭配使用,可將區塊定義新增至 Blockly.Blocks

const myBlockDefinitions = Blockly.common.createBlockDefinitionsFromJsonArray([
  {
    type: 'my_block1',
    // ...
  }
  {
    type: 'my_block3',
    // ...
  }
  {
    type: 'my_block2',
    // ...
  }
]);
Blockly.common.defineBlocks(myBlockDefinitions);

Block.jsonInit

jsonInit 會接受 JSON 物件,並對 Block 呼叫對應方法。舉例來說,含有鍵/值組合 colour: 150 的 JSON 物件會導致對 this.setColour(150) 的呼叫。在 init 函式中使用 jsonInit 載入 JSON 物件。

var myJson = {
  // ...
};

Blockly.Blocks['my_block'] = {
  init: function() {
    this.jsonInit(myJson);
    // The rest of the init function.
  }
};