คําจํากัดความของบล็อกจะอธิบายลักษณะและการทํางานของบล็อก ซึ่งได้แก่ ข้อความ สี รูปร่าง และการบล็อกอื่นๆ ที่บล็อกนั้นเชื่อมต่อได้
รูปแบบ 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
เป็นฟังก์ชันที่จะเรียกใช้เมื่อคลิกตัวเลือก