Blockly 有两种定义块的方式:使用键值对的 JSON 对象和调用 Blockly API 的 JavaScript 函数。JSON 格式是首选格式,因为它简化了本地化,并且更易于读写。不过,它不能用于直接定义高级功能,例如 mutator 或验证器。这些必须使用 JavaScript 编写,通常以扩展程序的形式编写。
使用 JSON 或 JavaScript
此代码块:

可以在 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'));
});
}
};
Block definition 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 对象数组,并返回一个将块类型名称映射到块定义的 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 调用相应的方法。例如,如果 JSON 对象包含键值对 colour: 150,则会调用 this.setColour(150)。在 init 函数中使用 jsonInit 加载 JSON 对象。
var myJson = {
// ...
};
Blockly.Blocks['my_block'] = {
init: function() {
this.jsonInit(myJson);
// The rest of the init function.
}
};