JSON และ JavaScript

Blockly มีวิธีกำหนดบล็อก 2 วิธี ได้แก่ ออบเจ็กต์ 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 จึงหมายถึงบล็อกจริงที่กำลังสร้างขึ้น

ทั้ง 2 วิธีจะส่งผลให้ออบเจ็กต์คำจำกัดความของบล็อกจัดเก็บไว้ใน 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 คือออบเจ็กต์ที่จัดเก็บคําจํากัดความของบล็อก คีย์คือชื่อประเภทบล็อก และค่าคือออบเจ็กต์คําจํากัดความของบล็อก ใช้ 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);

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