กําหนดการบล็อก

คําจํากัดความของบล็อกจะอธิบายลักษณะและการทํางานของบล็อก ซึ่งได้แก่ ข้อความ สี รูปร่าง และการบล็อกอื่นๆ ที่บล็อกนั้นเชื่อมต่อได้

รูปแบบ JSON เทียบกับ JavaScript API

Blockly มีวิธีการกำหนดบล็อก 2 วิธี ได้แก่ ออบเจ็กต์ JSON และฟังก์ชัน JavaScript รูปแบบ JSON ออกแบบมาเพื่อลดความซับซ้อนของกระบวนการแปลเมื่อพัฒนาสำหรับภาษาที่มีการเรียงลำดับคำต่างกัน รูปแบบ JSON เป็นวิธีที่แนะนำ ในการกำหนดบล็อก

อย่างไรก็ตาม รูปแบบ JSON กำหนดฟีเจอร์ขั้นสูงโดยตรงไม่ได้ เช่น การเปลี่ยนแปลงหรือโปรแกรมตรวจสอบ แท็กเหล่านี้จะเขียนด้วย JavaScript ซึ่งมักเป็นส่วนขยาย

แอปที่ใช้ JavaScript ดั้งเดิมของ Blockly จะเขียนคำจำกัดความบล็อกไปยังการเรียกใช้ฟังก์ชัน Blockly API ระดับล่างได้โดยตรง ดังที่แสดงในตัวอย่าง JavaScript ด้านล่าง

JSON

Blockly.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"
}]);

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

ฟังก์ชัน init จะสร้างรูปร่างของบล็อก ในบริบทของฟังก์ชันนี้ คีย์เวิร์ด this คือบล็อกจริงที่กำลังสร้างขึ้น

ตัวอย่างทั้งสองจะโหลดบล็อก "string_length" เดียวกัน

สำหรับในเว็บ ระบบจะโหลดรูปแบบ JSON โดยใช้ฟังก์ชัน initJson และยังเป็นการผสมทั้ง 2 รูปแบบในหน้าเว็บ Blockly ได้ด้วย ขอแนะนำให้กำหนดการบล็อกด้วย JSON ทุกครั้งที่ทำได้ และใช้ JavaScript สำหรับการกำหนดบล็อกบางส่วนที่ JSON ไม่รองรับเท่านั้น

ด้านล่างนี้เป็นตัวอย่างการบล็อกที่ระบุอย่างชัดเจนโดยใช้ JSON แต่มีการขยายโดยใช้ JavaScript API เพื่อแสดงเคล็ดลับเครื่องมือแบบไดนามิก

JavaScript

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() {
    this.jsonInit(mathChangeJson);
    // 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'));
    });
  }
};

บล็อกสี

สีหลักของบล็อกจะกำหนดโดยพร็อพเพอร์ตี้ JSON colour, ฟังก์ชัน block.setColour(..) หรือโดยการใช้ธีมและกำหนดรูปแบบบล็อก

JSON

{
  // ...,
  "colour": 160,
}

JavaScript

init: function() {
  // ...
  this.setColour(160);
}

ดูรายละเอียดเพิ่มเติมในคู่มือสีของบล็อก

การเชื่อมต่อของใบแจ้งยอด

ผู้ใช้จะสร้างลำดับบล็อกโดยใช้เครื่องมือเชื่อมต่อ nextStatement และ previousStatement ได้ ในเลย์เอาต์มาตรฐานของ Blockly เส้นเชื่อมต่อเหล่านี้จะ อยู่ด้านบนและด้านล่าง โดยจะมีบล็อกเรียงซ้อนกันในแนวตั้ง

บล็อกที่มีเครื่องมือเชื่อมต่อก่อนหน้าจะมีเครื่องมือเชื่อมต่อเอาต์พุตไม่ได้ และในทางกลับกันด้วย คำว่าบล็อกคำสั่งหมายถึงบล็อกที่ไม่มีเอาต์พุตค่า บล็อกคำสั่งมักจะมีทั้ง การเชื่อมต่อก่อนหน้าและการเชื่อมต่อถัดไป

การเชื่อมต่อ nextStatement และ previousStatement จะพิมพ์ได้ แต่บล็อกมาตรฐานจะใช้ฟีเจอร์นี้ไม่ได้

การเชื่อมต่อถัดไป

สร้างจุดที่ด้านล่างของบล็อกเพื่อให้คำสั่งอื่นๆ ซ้อนอยู่ใต้บล็อคได้ บล็อกที่มีการเชื่อมต่อถัดไปแต่ไม่มีการเชื่อมต่อก่อนหน้ามักจะแสดงถึงเหตุการณ์และกําหนดค่าให้แสดงผลด้วยหมวกได้

JSON

ไม่ได้พิมพ์:

{
  ...,
  "nextStatement": null,
}

ตัวพิมพ์ (หายาก):

{
  "nextStatement": "Action",
  ...
}

JavaScript

ไม่ได้พิมพ์:

this.setNextStatement(true);  // false implies no next connector, the default

ตัวพิมพ์ (หายาก):

this.setNextStatement(true, 'Action');

การเชื่อมต่อก่อนหน้า

จะสร้างรอยบากที่ด้านบนสุดของบล็อก เพื่อเชื่อมต่อเป็นกลุ่มคำสั่ง

บล็อกที่มีการเชื่อมต่อก่อนหน้านี้จะมีการเชื่อมต่อเอาต์พุตไม่ได้

JSON

ไม่ได้พิมพ์:

{
  ...,
  "previousStatement": null,
}

ตัวพิมพ์ (หายาก):

{
  "previousStatement": "Action",
  ...
}

JavaScript

ไม่ได้พิมพ์:

this.setPreviousStatement(true);  // false implies no previous connector, the default

ตัวพิมพ์ (หายาก):

this.setPreviousStatement(true, 'Action');

บล็อกเอาต์พุต

บล็อกหนึ่งๆ อาจมีเอาต์พุตเดี่ยว ซึ่งแสดงเป็นตัวต่อจิ๊กซอว์ตัวผู้ที่ขอบนำ เอาต์พุตจะเชื่อมต่อกับอินพุตค่า การบล็อกที่มีเอาต์พุตมักจะเรียกว่าการบล็อกค่า

JSON

ไม่ได้พิมพ์:

{
  // ...,
  "output": null,
}

พิมพ์แล้ว:

{
  // ...,
  "output": "Number",
}

JavaScript

ไม่ได้พิมพ์:

init: function() {
  // ...
  this.setOutput(true);
}

พิมพ์แล้ว:

init: function() {
  // ...
  this.setOutput(true, 'Number');
}

บล็อกที่มีเครื่องมือเชื่อมต่อเอาต์พุตต้องไม่มีรอยบากข้อความก่อนหน้า

บล็อกอินพุต

บล็อกจะมีอินพุตอย่างน้อย 1 รายการ โดยที่อินพุตแต่ละรายการจะมีลำดับช่องและอาจสิ้นสุดในการเชื่อมต่อ อินพุตในตัว มีหลายประเภท

  • อินพุตค่า: เชื่อมต่อกับการเชื่อมต่อเอาต์พุตของบล็อกค่า บล็อก math_arithmetic (การบวก การลบ) เป็นตัวอย่างของบล็อกที่มีอินพุตค่า 2 ค่า
  • อินพุตคำสั่ง: เชื่อมต่อกับการเชื่อมต่อก่อนหน้านี้ของบล็อกคำสั่ง ส่วนที่ซ้อนกันของลูปขณะคือตัวอย่างของอินพุตคำสั่ง
  • อินพุตจำลอง: ไม่มีการเชื่อมต่อแบบบล็อก ทำหน้าที่เหมือนขึ้นบรรทัดใหม่เมื่อกำหนดค่าการบล็อกให้ใช้อินพุตค่าภายนอก
  • อินพุตแถวสุดท้าย: ไม่มีการเชื่อมต่อแบบบล็อกและทํางานเหมือนการขึ้นบรรทัดใหม่เสมอ

นอกจากนี้ คุณยังสร้างอินพุตที่กำหนดเองเพื่อรองรับการแสดงผลที่กำหนดเองได้อีกด้วย

รูปแบบ JSON และ JavaScript API ใช้รูปแบบที่แตกต่างกันเล็กน้อยในการอธิบายอินพุต

อินพุตและช่องใน JSON

บล็อกที่กำหนดโดย JSON มีโครงสร้างเป็นลำดับของสตริงข้อความแทรก ( message0, message1, ...) โดยที่โทเค็นการประมาณค่าแต่ละรายการ (%1, %2, ...) คือช่องหรือจุดสิ้นสุดอินพุต (ซึ่งจะทำให้เครื่องมือเชื่อมต่ออินพุตแสดงผลภายในข้อความ) ในอาร์เรย์ JSON argsN ที่ตรงกัน รูปแบบนี้มีไว้เพื่อทำให้การปรับให้เป็นสากลเป็นเรื่องง่าย

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

โทเค็นการประมาณค่าต้องตรงกับอาร์เรย์ args0 ทั้งหมด กล่าวคือไม่ซ้ำ ไม่มีการละเว้น โทเค็นอาจแสดงในลำดับใดก็ได้ ซึ่งทำให้ภาษาต่างๆ เปลี่ยนเลย์เอาต์ของการบล็อกได้

ข้อความด้านใดด้านหนึ่งของโทเค็นการประมาณค่าถูกตัดเว้นวรรค ข้อความที่ใช้อักขระ % (เช่น เมื่อหมายถึงเปอร์เซ็นต์) ควรใช้ %% เพื่อไม่ให้ระบบตีความว่าเป็นโทเค็นการประมาณค่า

ลำดับของอาร์กิวเมนต์และประเภทอาร์กิวเมนต์จะเป็นตัวกำหนดรูปร่างของบล็อก การเปลี่ยนสตริงใดสตริงหนึ่งเหล่านี้อาจเปลี่ยนแปลงเลย์เอาต์ของบล็อกอย่างสิ้นเชิง วิธีนี้มีความสำคัญอย่างยิ่งในภาษาที่มีลำดับคำต่างจากภาษาอังกฤษ ลองพิจารณาภาษาสมมติที่ต้องมีการกลับ "set %1 to %2" (ตามที่ใช้ในตัวอย่างด้านบน) เป็น "put %2 in %1" การเปลี่ยนสตริงนี้เพียงสตริงเดียว (และปล่อยส่วนที่เหลือของ JSON ไว้ตามเดิม) จะทำให้เกิดบล็อกต่อไปนี้

Blockly เปลี่ยนลำดับของช่อง สร้างอินพุตจำลอง และเปลี่ยนจากอินพุตภายนอกเป็นอินพุตภายในโดยอัตโนมัติ

นอกจากนี้ Blockly จะแทนที่อักขระสำหรับการขึ้นบรรทัดใหม่ (\n) ในสตริงข้อความโดยอัตโนมัติด้วยการป้อนข้อมูลแถวแนวนอน

JSON

{
  "message0": "set %1\nto %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

อาร์กิวเมนต์

สตริงข้อความแต่ละรายการจะจับคู่กับอาร์เรย์ args ที่มีตัวเลขเดียวกัน ตัวอย่างเช่น message0 จะตามด้วย args0 โทเค็นการประมาณค่า (%1, %2, ...) อ้างถึงรายการของอาร์เรย์ args ออบเจ็กต์ทั้งหมดมีสตริง type พารามิเตอร์อื่นๆ ที่เหลือจะแตกต่างกันไปตามประเภทดังนี้

คุณยังสามารถกำหนดช่องที่กำหนดเองและอินพุตที่กำหนดเองและส่งผ่านเป็นอาร์กิวเมนต์ได้อีกด้วย

ออบเจ็กต์ทุกรายการอาจมีช่อง alt ได้ด้วย ในกรณีที่ Blockly ไม่รู้จัก type ของออบเจ็กต์ ระบบจะใช้ออบเจ็กต์ alt แทน เช่น หากเพิ่มช่องใหม่ชื่อ field_time ลงใน Blockly การบล็อกที่ใช้ช่องนี้อาจใช้ alt เพื่อกำหนด field_input สำรองสำหรับ Blockly เวอร์ชันเก่า ดังนี้

JSON

{
  "message0": "sound alarm at %1",
  "args0": [
    {
      "type": "field_time",
      "name": "TEMPO",
      "hour": 9,
      "minutes": 0,
      "alt":
        {
          "type": "field_input",
          "name": "TEMPOTEXT",
          "text": "9:00"
        }
    }
  ]
}

ออบเจ็กต์ alt อาจมีออบเจ็กต์ alt ของตัวเอง จึงทำให้ทำการเชนได้ ในท้ายที่สุด หาก Blockly สร้างออบเจ็กต์ในอาร์เรย์ args0 ไม่ได้ (หลังจากลองออบเจ็กต์ alt รายการใดก็ตาม) ระบบจะข้ามออบเจ็กต์นั้น

ระบบจะเพิ่มอินพุตจำลองลงในตอนท้ายของบล็อกโดยอัตโนมัติ หากสตริง message ลงท้ายด้วยข้อความหรือช่องที่ไม่ได้อยู่ในอินพุต ดังนั้นหากอินพุตสุดท้ายในบล็อกเป็นอินพุตจำลอง ระบบจึงละเว้นอินพุตดังกล่าวจากอาร์เรย์ args และไม่จำเป็นต้องมีการประมาณค่าในช่วง message การเพิ่มอินพุตจำลองแบบอัตโนมัติช่วยให้นักแปลเปลี่ยน message ได้โดยไม่ต้องแก้ไข JSON ส่วนที่เหลือ ดูตัวอย่างของ "set %1 to %2" (ไม่มีอินพุตจำลอง) และ "put %2 in %1" (เพิ่มอินพุตจำลอง) ก่อนหน้านี้ในหน้านี้

implicitAlign0

ในบางกรณีที่เกิดขึ้นไม่บ่อยนัก อินพุตจำลองแบบต่อท้ายที่สร้างขึ้นโดยอัตโนมัติจะต้องสอดคล้องกับ "RIGHT" หรือ "CENTRE" ค่าเริ่มต้นหากไม่ได้ระบุไว้คือ "LEFT"

ในตัวอย่างด้านล่าง message0 คือ "send email to %1 subject %2 secure %3" และ Blockly จะเพิ่มอินพุตจำลองสำหรับแถวที่ 3 โดยอัตโนมัติ การตั้งค่า implicitAlign0 เป็น "RIGHT" จะบังคับให้แถวนี้อยู่ในแนวขวา การปรับแนวนี้มีผลกับอินพุตทั้งหมดที่ไม่ได้กําหนดอย่างชัดแจ้งในคําจํากัดความของบล็อก JSON ซึ่งรวมถึงอินพุตแถวสุดท้ายที่แทนที่อักขระขึ้นบรรทัดใหม่ ('\n') ในข้อความ นอกจากนี้ ยังมีพร็อพเพอร์ตี้ lastDummyAlign0 ที่เลิกใช้งานแล้วซึ่งมีลักษณะการทำงานเหมือนกับ implicitAlign0 ด้วย

เมื่อออกแบบบล็อกตัวอักษรจากขวาไปซ้าย (อาหรับและฮีบรู) จะกลับด้านซ้ายและขวา ดังนั้น "RIGHT" จะจัดเรียงช่องไปทางซ้าย

message1, args1, implicitAlign1

โดยปกติแล้ว บางบล็อกแบ่งออกเป็น 2 ส่วนขึ้นไปแยกกัน พิจารณาช่องการทำซ้ำนี้ซึ่งมี 2 แถว

หากอธิบายการบล็อกนี้ด้วยข้อความเดียว พร็อพเพอร์ตี้ message0 จะเป็น "repeat %1 times %2 do %3" สตริงนี้ไม่ค่อยเข้าใจสำหรับนักแปล และยากที่จะอธิบายว่าการใช้แทน %2 หมายถึงอะไร อินพุตจำลอง %2 อาจไม่เป็นที่ต้องการในบางภาษาด้วย และอาจมีหลายบล็อก ที่ต้องการแชร์ข้อความของแถวที่ 2 วิธีที่ดีกว่าคือให้ JSON ใช้พร็อพเพอร์ตี้ข้อความและอาร์กิวเมนต์มากกว่า 1 รายการ

JSON

{
  "type": "controls_repeat_ext",
  "message0": "repeat %1 times",
  "args0": [
    {"type": "input_value", "name": "TIMES", "check": "Number"}
  ],
  "message1": "do %1",
  "args1": [
    {"type": "input_statement", "name": "DO"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 120
}

พร็อพเพอร์ตี้ message, args และ implicitAlign จำนวนเท่าใดก็ได้ในรูปแบบ JSON โดยเริ่มด้วย 0 และเพิ่มขึ้นตามลำดับ โปรดทราบว่า Block Factory ไม่สามารถแยกข้อความออกเป็นหลายส่วนได้ แต่การแยกข้อความด้วยตนเองนั้นทำได้ง่าย

อินพุตและช่องใน JavaScript

JavaScript API มีเมธอด append สำหรับอินพุตแต่ละประเภท ดังนี้

JavaScript

this.appendEndRowInput()
    .appendField('for each')
    .appendField('item')
    .appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
    .setCheck('Array')
    .setAlign(Blockly.inputs.Align.RIGHT)
    .appendField('in list');
this.appendStatementInput('DO')
    .appendField('do');
this.appendDummyInput()
    .appendField('end');

การต่อท้ายแต่ละวิธีสามารถรับสตริงตัวระบุที่โปรแกรมสร้างโค้ดใช้ อินพุตจำลองและอินพุตแถวสุดท้ายแทบไม่ต้องใช้การอ้างอิงและตัวระบุมักจะไม่มีการตั้งค่า

JavaScript API ยังมีเมธอด appendInput ทั่วไปสำหรับต่อท้ายอินพุตที่กำหนดเองอีกด้วย โปรดทราบว่าในกรณีนี้ ตัวระบุควรส่งผ่าน ไปยังตัวสร้างอินพุตที่กำหนดเองโดยตรง

JavaScript

this.appendInput(new MyCustomInput('INPUT_NAME'))
    .appendField('an example label')

เมธอด appendInput ทั้งหมด (ทั้งทั่วไปและไม่ใช่ทั่วไป) จะแสดงออบเจ็กต์อินพุตเพื่อให้กำหนดค่าเพิ่มเติมได้โดยใช้เชนเมธอด การกำหนดค่าอินพุตทำได้ 3 วิธีด้วยกัน

setCheck

JavaScript

input.setCheck('Number');

ฟังก์ชันเสริมนี้ใช้สำหรับการตรวจสอบประเภทของอินพุตที่เชื่อมต่อ หากมีอาร์กิวเมนต์เป็น Null ค่าเริ่มต้น อินพุตนี้อาจเชื่อมต่อกับบล็อกใดก็ได้ โปรดดูรายละเอียดในการตรวจสอบประเภท

setAlign

JavaScript

input.setAlign(Blockly.inputs.Align.RIGHT);

ฟังก์ชันที่ไม่บังคับนี้ใช้เพื่อปรับแนวฟิลด์ (ดูด้านล่าง) ค่าที่อธิบายตัวเองมีอยู่ 3 ค่าซึ่งอาจส่งผ่านเป็นอาร์กิวเมนต์ไปยังฟังก์ชันนี้ ได้แก่ Blockly.inputs.Align.LEFT, Blockly.inputs.Align.RIGHT และ Blockly.inputs.Align.CENTER

เมื่อออกแบบบล็อกตัวอักษรจากขวาไปซ้าย (อาหรับและฮีบรู) จะกลับด้านซ้ายและขวา ดังนั้น Blockly.inputs.Align.RIGHT จะจัดเรียงช่องไปทางซ้าย

appendField

เมื่อสร้างอินพุตและต่อท้ายบล็อกด้วย appendInput แล้ว ช่องหนึ่งอาจเพิ่มช่องกี่ช่องก็ได้ต่อท้ายอินพุต ช่องเหล่านี้มักใช้เป็นป้ายกำกับเพื่ออธิบายว่าอินพุตแต่ละรายการมีไว้เพื่ออะไร

JavaScript

input.appendField('hello');

องค์ประกอบของช่องที่เรียบง่ายที่สุดคือข้อความ รูปแบบของ Blockly คือการใช้ข้อความที่เป็นตัวพิมพ์เล็กทั้งหมด ยกเว้นชื่อเฉพาะ (เช่น Google, SQL)

แถวอินพุตอาจมีองค์ประกอบช่องกี่รายการก็ได้ การเรียก appendField หลายรายการอาจเชื่อมโยงกันเพื่อเพิ่มช่องหลายช่องลงในแถวอินพุตเดียวกันได้อย่างมีประสิทธิภาพ

JavaScript

input.appendField('hello')
     .appendField(new Blockly.FieldLabel('Neil', 'person'));

การเรียก appendField('hello') เป็นทางลัดสำหรับตัวสร้าง FieldLabel อย่างชัดแจ้ง นั่นคือ appendField(new Blockly.FieldLabel('hello')) สิ่งเดียวที่คุณต้องการใช้ตัวสร้างคือเมื่อระบุชื่อคลาสเพื่อให้จัดรูปแบบข้อความโดยใช้กฎ CSS ได้

แบบแทรกในบรรทัดกับภายนอก

บล็อกอินพุตสามารถแสดงผลเป็นภายนอกหรือภายในก็ได้

คำจำกัดความของบล็อกสามารถระบุบูลีนที่ไม่บังคับซึ่งควบคุมว่าอินพุตจะแทรกในบรรทัดหรือไม่ หากเป็น false อินพุตค่าใดๆ จะเป็นค่าภายนอก (เช่น บล็อกด้านซ้าย) หากตั้งค่าเป็น true ค่าที่ป้อนจะเป็นแบบในหน้า (เช่น บล็อกด้านขวาด้านบน)

JSON

{
  // ...,
  "inputsInline": true
}

JavaScript

init: function() {
  // ...
  this.setInputsInline(true);
}

หากไม่ได้กำหนด Blockly จะใช้วิธีการบางอย่างเพื่อคาดเดาว่าโหมดใดเหมาะสมที่สุด สมมติว่า Blockly ตัดสินใจถูกแล้ว การปล่อยช่องนี้ให้ว่างไว้จะสะดวกกว่า เนื่องจากการแปลภาษาต่างๆ จะมีโหมดที่แตกต่างกันโดยอัตโนมัติ ดูตัวอย่าง JSON ของ "set %1 to %2" (อินพุตภายนอก) และ "put %2 in %1" (อินพุตในหน้า) ก่อนหน้านี้ในหน้านี้

ใช้อินพุตแบบอินไลน์เมื่อบล็อกมีแนวโน้มที่จะมีอินพุตเล็กน้อย เช่น ตัวเลข ผู้ใช้จะสลับตัวเลือกนี้ผ่านเมนูตามบริบทได้หากเปิดใช้การกำหนดค่า collapse ไว้ (ค่าเริ่มต้นจะเป็น true หากกล่องเครื่องมือมีหมวดหมู่)

ช่อง

ช่องจะกำหนดองค์ประกอบ UI ส่วนใหญ่ภายในบล็อก ซึ่งรวมถึงป้ายกำกับสตริง รูปภาพ และอินพุตสำหรับข้อมูลตามตัวอักษร เช่น สตริงและตัวเลข ตัวอย่างที่ง่ายที่สุดคือการบล็อก math_number ซึ่งใช้ field_input เพื่อให้ผู้ใช้พิมพ์ตัวเลขได้

ช่องจะต่อท้ายการบล็อกโดยใช้ appendField

Blockly มีช่องในตัวจำนวนหนึ่งให้ ซึ่งรวมถึงการป้อนข้อความ ตัวเลือกสี และรูปภาพ คุณยังสร้างช่องของตัวเองได้อีกด้วย

→ ข้อมูลเพิ่มเติมเกี่ยวกับช่องในตัว

→ ข้อมูลเพิ่มเติมเกี่ยวกับการสร้างช่องที่กำหนดเอง

ไอคอน

ไอคอนจะกำหนดองค์ประกอบ UI บนบล็อกที่แสดงข้อมูล "เมตา" เกี่ยวกับการบล็อก

จะมีไอคอน addIcon ต่อท้ายการบล็อก

Blockly มีไอคอนในตัวจำนวนหนึ่ง ซึ่งรวมถึงไอคอนความคิดเห็นและไอคอนคำเตือน คุณยังสามารถสร้างไอคอนของคุณเองได้อีกด้วย

→ ข้อมูลเพิ่มเติมเกี่ยวกับการสร้างไอคอนที่กำหนดเอง

เคล็ดลับเครื่องมือ

เคล็ดลับเครื่องมือจะให้ความช่วยเหลือได้ทันทีเมื่อผู้ใช้วางเมาส์เหนือบล็อก หากข้อความยาว ระบบจะตัดข้อความออกโดยอัตโนมัติ

JSON

{
  // ...,
  "tooltip": "Tooltip text."
}

JavaScript

init: function() {
  this.setTooltip("Tooltip text.");
}

ใน JavaScript API คุณยังกำหนดเคล็ดลับเครื่องมือเป็นฟังก์ชันแทนสตริงแบบคงที่ได้ ซึ่งจะช่วยให้ดำเนินการช่วยเหลือแบบไดนามิกได้ โปรดดู math_arithmetic สำหรับตัวอย่างเคล็ดลับเครื่องมือที่เปลี่ยนแปลงไปตามตัวเลือกในเมนูแบบเลื่อนลงที่เลือก

JavaScript

Blockly.Blocks['math_arithmetic'] = {
  init: function() {
    // ...

    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var mode = thisBlock.getFieldValue('OP');
      var TOOLTIPS = {
        'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
        'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
        'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
        'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
        'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
      };
      return TOOLTIPS[mode];
    });
  }
};

เมื่อใช้ JavaScript API บล็อกจะระบุฟังก์ชันแทนสตริงแบบคงที่ ซึ่งจะแสดงผลสตริงเคล็ดลับเครื่องมือได้ ซึ่งจะทำให้สามารถใช้เคล็ดลับเครื่องมือแบบไดนามิกได้ ดูตัวอย่างได้ที่ math_arithmetic

ปรับแต่งเฉพาะคน

คุณปรับแต่งรูปลักษณ์ของเคล็ดลับเครื่องมือได้ด้วยการกำหนดฟังก์ชันการแสดงผลที่กำหนดเอง สร้างฟังก์ชันที่ยอมรับพารามิเตอร์ 2 รายการดังนี้

  • อย่างแรก องค์ประกอบ <div> ที่คุณจะแสดงเนื้อหา
  • องค์ประกอบจริงที่วางเมาส์เหนือองค์ประกอบ และคุณจะแสดงเคล็ดลับเครื่องมือ

ในส่วนเนื้อหาของฟังก์ชัน คุณแสดงผลเนื้อหาใดก็ได้ที่ต้องการลงใน div ในการรับสตริงเคล็ดลับเครื่องมือที่กำหนดไว้ในบล็อกที่เมาส์อยู่ คุณสามารถเรียกใช้ Blockly.Tooltip.getTooltipOfObject(element); โดยที่ element เป็นพารามิเตอร์ที่ 2 ด้านบน

สุดท้าย ลงทะเบียนฟังก์ชันนี้เพื่อให้ Blockly เรียกใช้ฟังก์ชันนี้ในเวลาที่เหมาะสม

Blockly.Tooltip.setCustomTooltip(yourFnHere);

ดูตัวอย่างได้ที่การสาธิตเคล็ดลับเครื่องมือที่กำหนดเอง

URL ของความช่วยเหลือ

การบล็อกอาจมีหน้าความช่วยเหลือที่เชื่อมโยงอยู่ ฟีเจอร์นี้พร้อมให้บริการแก่ผู้ใช้ Blockly for Web โดยคลิกขวาที่การบล็อกและเลือก "ความช่วยเหลือ" จากเมนูบริบท หากค่านี้เป็น null เมนูจะเป็นสีเทา

JSON

{
  // ...,
  "helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}

JavaScript

init: function() {
  // ...
  this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}

เมื่อใช้ JavaScript API บล็อกจะระบุฟังก์ชันแทนสตริงแบบคงที่ ซึ่งจะแสดงผลสตริง URL จึงช่วยให้เกิดความช่วยเหลือแบบไดนามิกได้

เปลี่ยน Listener และโปรแกรมตรวจสอบ

การบล็อกอาจเปลี่ยนแปลงฟังก์ชัน Listener ที่เรียกใช้การเปลี่ยนแปลงในพื้นที่ทำงาน (รวมถึงฟังก์ชันที่ไม่เกี่ยวข้องกับการบล็อก) ข้อความเหล่านี้มีไว้เพื่อกำหนดข้อความเตือนของการบล็อกหรือการแจ้งเตือนผู้ใช้ที่คล้ายกันนอกพื้นที่ทำงานเป็นหลัก

ระบบจะเพิ่มฟังก์ชันนี้โดยเรียกใช้ setOnChange ด้วยฟังก์ชัน และสามารถดำเนินการได้ในช่วงเริ่มต้นหรือผ่านส่วนขยาย JSON หากวางแผนที่จะใช้ในทุกแพลตฟอร์ม

JSON

{
  // ...,
  "extensions":["warning_on_change"],
}

Blockly.Extensions.register('warning_on_change', function() {
  // Example validation upon block change:
  this.setOnChange(function(changeEvent) {
    if (this.getInput('NUM').connection.targetBlock()) {
      this.setWarningText(null);
    } else {
      this.setWarningText('Must have an input block.');
    }
  });
});

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.setOnChange(function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    });
  }
}

ระบบจะเรียกใช้ฟังก์ชันนี้โดยผ่านในเหตุการณ์การเปลี่ยนแปลง ภายในฟังก์ชัน this หมายถึงอินสแตนซ์บล็อก

เนื่องจากมีการเรียกใช้ฟังก์ชันเมื่อมีการเปลี่ยนแปลง นักพัฒนาซอฟต์แวร์จึงควรตรวจสอบว่า Listener ทำงานได้อย่างรวดเร็ว นอกจากนี้ควรระวังเรื่องการเปลี่ยนแปลงพื้นที่ทำงาน ที่อาจเรียงต่อกันหรือวนกลับไปที่ผู้ฟัง

ดูตัวอย่างการบล็อก controls_flow_statements, logic_compare และ procedures_ifreturn

โปรดทราบว่าช่องที่แก้ไขได้จะมี Listener เหตุการณ์ของตัวเองสำหรับการตรวจสอบอินพุต และทำให้เกิดผลข้างเคียง

ตัวเปลี่ยนแปลง

การเปลี่ยนแปลงจะช่วยให้บล็อกขั้นสูงเปลี่ยนรูปร่างได้ โดยเฉพาะอย่างยิ่งเมื่อผู้ใช้เปิดกล่องโต้ตอบเพื่อเพิ่ม นำออก หรือจัดเรียงคอมโพเนนต์ใหม่ การเพิ่มตัวแปรผ่าน JSON ด้วยคีย์ mutator ได้

JSON

{
  // ...,
  "mutator":"if_else_mutator"
}

การกำหนดค่าต่อการบล็อก

อินสแตนซ์ที่บล็อกมีพร็อพเพอร์ตี้หลายรายการที่กำหนดลักษณะการทำงานของผู้ใช้ ซึ่งใช้เพื่อจำกัดพื้นที่ทำงานให้แสดงพร็อพเพอร์ตี้บางอย่างของโดเมนได้ (เช่น มีเหตุการณ์ "เริ่มต้น" 1 รายการ) หรือจะเน้นความพยายามของผู้ใช้ (เช่น บทแนะนำ) ก็ได้

สถานะที่ลบได้

block.setDeletable(false);

เมื่อตั้งค่าเป็น "เท็จ" ผู้ใช้จะลบการบล็อกไม่ได้ การบล็อกตามค่าเริ่มต้นจะสามารถลบได้บนพื้นที่ทำงานที่แก้ไขได้

ระบบอาจลบการบล็อกทั้งหมด (แม้แต่บล็อกที่เข้าถึงไม่ได้) แบบเป็นโปรแกรมในกรณีต่อไปนี้

block.dispose();

สถานะที่แก้ไขได้

block.setEditable(false);

เมื่อตั้งค่าเป็น "เท็จ" ผู้ใช้จะเปลี่ยนแปลงช่องของบล็อกไม่ได้ (เช่น เมนูแบบเลื่อนลงและการป้อนข้อความ) การบล็อกตามค่าเริ่มต้นที่จะแก้ไขได้ในพื้นที่ทำงานที่แก้ไขได้

สถานะเคลื่อนย้ายได้

block.setMovable(false);

เมื่อตั้งค่าเป็น "เท็จ" ผู้ใช้จะย้ายการบล็อกโดยตรงไม่ได้ บล็อกที่ย้ายไม่ได้ซึ่งเป็นบล็อกย่อยของอีกบล็อกหนึ่งอาจไม่สามารถยกเลิกการเชื่อมต่อกับบล็อกนั้นได้ แต่บล็อกนั้นจะย้ายไปพร้อมกับบล็อกหลักหากย้ายระดับบนสุด การบล็อกตามค่าเริ่มต้นที่จะย้ายได้บนพื้นที่ทำงานที่แก้ไขได้

การบล็อกใดๆ (แม้แต่บล็อกที่ย้ายไม่ได้) อาจย้ายแบบเป็นโปรแกรมเมื่อบล็อกอยู่ในพื้นที่ทำงานแล้ว

block.moveBy(dx, dy)

ตำแหน่งเริ่มต้นสำหรับบล็อกในพื้นที่ทำงานจะมีค่าเริ่มต้นเป็น (0, 0)

บล็อกเน็ตมือถือ

this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db';

ข้อมูลเป็นสตริงที่ไม่บังคับและเป็นสตริงที่กำหนดเองที่แนบมากับการบล็อก เมื่อบล็อกถูกทำให้เป็นอนุกรม สตริงข้อมูลจะถูกทำให้เป็นอนุกรม ซึ่งรวมถึงเมื่อมีการคัดลอก/วางการบล็อก

ซึ่งมักใช้เพื่อเชื่อมโยงการบล็อกกับทรัพยากรภายนอก

เมื่อทำให้เป็น JSON แบบอนุกรม ระบบจะจัดเก็บข้อมูลเป็นพร็อพเพอร์ตี้ระดับบนสุดในบล็อก

{
  "type": "my_block",
  "data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db",
  // etc..
}

เมื่อทำให้เป็น XML (ระบบการทำให้เป็นอนุกรมแบบใช้ Iceboxed เดิม) สตริงข้อมูลจะจัดเก็บในแท็ก <data></data> ภายในบล็อก ดังนี้

<block type="my_block">
  <data>16dcb3a4-bd39-11e4-8dfc-aa07a5b093db</data>
  <!-- etc... -->
</block>

การทำลาย

บล็อกมีฮุก destroy ซึ่งจะเรียกใช้เมื่อถูกลบออกจากพื้นที่ทำงาน ซึ่งอาจใช้เพื่อทำลายโมเดลข้อมูลสนับสนุน/ทรัพยากรภายนอกที่เชื่อมโยงกับการบล็อกที่ไม่จำเป็นอีกต่อไป

JSON

{
  // ...,
  "extensions":["destroy"],
}

Blockly.Extensions.registerMixin('destroy', {
  destroy: function() {
    this.myResource.dispose();
  }
});

JavaScript

Blockly.Blocks['block_type'] = {
  destroy: function() {
    this.myResource.dispose();
  }
}

ระบบจะเรียกใช้เมธอด destroy หลังจากที่กำจัดหน่วยโฆษณาระดับบนสุดของการบล็อกแล้ว แต่ก่อนที่จะมีการกำจัดเมธอดย่อยหรือช่องใดๆ ของการบล็อก

เมนูบริบท

โดยค่าเริ่มต้น การบล็อกจะมีเมนูตามบริบทที่แสดงแบบคลิกขวาซึ่งอนุญาตให้ผู้ใช้ทำสิ่งต่างๆ เช่น เพิ่มความคิดเห็น หรือบล็อกทำซ้ำ

คุณปิดใช้เมนูตามบริบทของการบล็อกแต่ละรายการได้ดังนี้

block.contextMenu = false;

คุณยังสามารถปรับแต่งตัวเลือกที่แสดงในเมนูได้อีกด้วย หากต้องการปรับแต่งเมนูสำหรับบล็อกทั้งหมด โปรดดูเอกสารประกอบเกี่ยวกับเมนูตามบริบท หากต้องการปรับแต่งเมนูสำหรับการบล็อกแต่ละรายการ ให้ใช้ customContextMenu ฟังก์ชันนี้ใช้อาร์เรย์ของตัวเลือกเมนูและปรับเปลี่ยนในตำแหน่งต่างๆ ซึ่งหมายความว่าคุณเพิ่มและนำรายการออกได้

ตัวเลือกเมนูแต่ละรายการเป็นออบเจ็กต์ที่มีพร็อพเพอร์ตี้ 3 รายการ ดังนี้

  • text คือข้อความที่แสดง
  • enabled เป็นบูลีน เมื่อปิดใช้ ตัวเลือกจะแสดงแต่จะเป็นข้อความสีเทา
  • callback เป็นฟังก์ชันที่จะเรียกใช้เมื่อคลิกตัวเลือก