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.
  }
};