JSON i JavaScript

Blockly umożliwia definiowanie bloków na 2 sposoby: za pomocą obiektów JSON, które używają par klucz-wartość, oraz funkcji JavaScript, które wywołują interfejs API Blockly. Preferowany jest format JSON, ponieważ upraszcza lokalizację i jest łatwiejszy do odczytu i zapisu. Nie można go jednak używać do bezpośredniego definiowania funkcji zaawansowanych, takich jak mutatory czy walidatory. Muszą one być napisane w JavaScript, zwykle jako rozszerzenia.

Używanie formatu JSON lub JavaScript

Ten blok:

Blok `string_length`.

można zdefiniować w formacie JSON lub JavaScript w ten sposób.

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 konwertuje każdy obiekt JSON na obiekt definicji bloku z funkcją init. Przechowuje te obiekty w 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');
  }
};

Ponieważ obiekty definicji bloków są mieszane z obiektami bloków, słowo kluczowe this odnosi się do tworzonego bloku.

Obie metody powodują, że obiekt definicji bloku jest przechowywany w Blockly.Blocks z kluczem nazwy typu bloku (string_length). Obiekt definicji bloku ma jedną metodę (init), która definiuje kształt bloku.

Łączenie formatu JSON i JavaScript

Format JSON obsługuje przede wszystkim definiowanie wyglądu bloku. Nie można bezpośrednio zdefiniować niektórych funkcji, takich jak walidatory i mutatory, które wymagają zdefiniowania funkcji. Aby rozwiązać ten problem, zdefiniuj jak najwięcej bloku za pomocą formatu JSON, a resztę za pomocą JavaScript.

Poniższy przykład tworzy definicję bloku z funkcją init, która używa jsonInit do wczytania obiektu JSON i interfejsu API JavaScript do zdefiniowania dynamicznego dymku.

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

Interfejs API definicji bloku

W tej sekcji znajdziesz podsumowanie obiektów i funkcji używanych do definiowania bloków niestandardowych.

Blockly.Blocks

Blockly.Blocks to obiekt, który przechowuje definicje bloków. Jego kluczami są nazwy typów bloków, a wartościami – obiekty definicji bloków. Podczas definiowania bloków za pomocą JavaScript użyj Blockly.Blocks:

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

Częstym błędem jest założenie, że Blockly.Blocks przechowuje bloki, i próba wykonania czegoś takiego. To się nie uda, ponieważ Blockly.Blocks przechowuje definicje bloków, a nie bloki.

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

defineBlocksWithJsonArray

defineBlocksWithJsonArray akceptuje tablicę obiektów JSON, tworzy z nich definicje bloków i dodaje je do Blockly.Blocks.

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

createBlockDefinitionsFromJsonArray i defineBlocks

createBlockDefinitionsFromJsonArray akceptuje tablicę obiektów JSON i zwraca obiekt, który mapuje nazwy typów bloków na definicje bloków. Jest on zwykle używany z defineBlocks, który dodaje definicje bloków do Blockly.Blocks.

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

Block.jsonInit

jsonInit akceptuje obiekt JSON i wywołuje odpowiednie metody w Block. Na przykład obiekt JSON z parą klucz-wartość colour: 150 powoduje wywołanie this.setColour(150). Aby wczytać obiekt JSON, użyj jsonInit w funkcji init.

var myJson = {
  // ...
};

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