JSON и JavaScript

Blockly имеет два способа определения блоков: объекты JSON, которые используют пары ключ-значение, и функции JavaScript, которые вызывают API Blockly. Формат 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 преобразует каждый объект JSON в объект определения блока с помощью функции init . Он хранит эти объекты в 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 и API JavaScript для определения динамической всплывающей подсказки.

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['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);

Блок.jsonInit

jsonInit принимает объект JSON и вызывает соответствующие методы Block . Например, объект JSON с парой ключ-значение colour: 150 приводит к вызову this.setColour(150) . Используйте jsonInit в функции init для загрузки объекта JSON.

var myJson = {
  // ...
};

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