Xác định khối

Định nghĩa khối mô tả giao diện và hành vi của một khối, bao gồm văn bản, màu sắc, hình dạng và các khối khác có thể kết nối.

Định dạng JSON so với API JavaScript

Blockly có hai cách xác định khối: đối tượng JSON và hàm JavaScript. Định dạng JSON được thiết kế để đơn giản hoá quá trình bản địa hoá khi phát triển cho các ngôn ngữ có thứ tự từ khác nhau. Định dạng JSON là phương thức ưu tiên để xác định các khối.

Tuy nhiên, định dạng JSON không thể trực tiếp xác định các tính năng nâng cao, chẳng hạn như biến thể hoặc trình xác thực. Những nội dung này phải được viết bằng JavaScript, thường ở dạng phần mở rộng.

Các ứng dụng sử dụng cách triển khai JavaScript ban đầu của Blockly cũng có thể ghi trực tiếp định nghĩa khối vào các lệnh gọi hàm Blockly API ở cấp thấp hơn, như minh hoạ trong nhiều ví dụ về JavaScript dưới đây.

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

Hàm init tạo hình dạng của khối. Trong ngữ cảnh của hàm này, từ khoá this là khối thực sự đang được tạo.

Cả hai ví dụ đều tải cùng một khối "string_length".

Trên web, định dạng JSON được tải bằng hàm initJson. Điều này cũng cho phép kết hợp hai định dạng trong các trang web Chặn. Bạn nên xác định khối của mình bằng JSON bất cứ khi nào có thể và chỉ sử dụng JavaScript cho các phần định nghĩa khối mà JSON không hỗ trợ.

Dưới đây là ví dụ về một khối chủ yếu được xác định bằng JSON, nhưng được mở rộng bằng cách sử dụng API JavaScript để làm nổi bật chú giải công cụ động.

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

Màu khối

Màu chính của một khối được xác định bằng thuộc tính colour JSON, hàm block.setColour(..) hoặc bằng cách sử dụng giao diện và xác định kiểu khối.

JSON

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

JavaScript

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

Vui lòng xem hướng dẫn về màu khối để biết thêm thông tin chi tiết.

Kết nối câu lệnh

Người dùng có thể tạo trình tự các khối bằng trình kết nối nextStatementpreviousStatement. Trong bố cục tiêu chuẩn của Blockly, các kết nối này nằm ở trên cùng và dưới cùng, với các khối được xếp chồng theo chiều dọc.

Một khối có trình kết nối trước đó không thể có trình kết nối đầu ra và ngược lại. Thuật ngữ khối câu lệnh dùng để chỉ một khối không có giá trị đầu ra. Khối câu lệnh thường sẽ có cả kết nối trước đó và kết nối tiếp theo.

Bạn có thể nhập các kết nối nextStatementpreviousStatement, nhưng tính năng này không được sử dụng trong các khối tiêu chuẩn.

Kết nối tiếp theo

Tạo một điểm ở cuối khối để các câu lệnh khác có thể được xếp chồng bên dưới. Một khối có kết nối tiếp theo nhưng không có kết nối trước đó nào thường đại diện cho một sự kiện và có thể được định cấu hình để hiển thị bằng .

JSON

Chưa nhập:

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

Đã nhập (hiếm):

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

JavaScript

Chưa nhập:

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

Đã nhập (hiếm):

this.setNextStatement(true, 'Action');

Mối kết nối trước

Tạo một vết khía ở đầu khối để có thể được kết nối dưới dạng một ngăn xếp các câu lệnh.

Các khối có kết nối trước đó không thể có kết nối đầu ra.

JSON

Chưa nhập:

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

Đã nhập (hiếm):

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

JavaScript

Chưa nhập:

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

Đã nhập (hiếm):

this.setPreviousStatement(true, 'Action');

Chặn đầu ra

Một khối có thể có một đầu ra duy nhất, được biểu thị dưới dạng trình kết nối ghép hình đực ở cạnh trên. Đầu ra kết nối với đầu vào giá trị. Các khối có dữ liệu đầu ra thường được gọi là khối giá trị.

JSON

Chưa nhập:

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

Đã nhập:

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

JavaScript

Chưa nhập:

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

Đã nhập:

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

Các khối có trình kết nối đầu ra cũng không được có khía câu lệnh trước đó.

Chặn đầu vào

Một khối có một hoặc nhiều đầu vào, trong đó mỗi đầu vào có một chuỗi các trường và có thể kết thúc bằng một kết nối. Có một số loại dữ liệu đầu vào tích hợp sẵn.

  • Giá trị đầu vào: Kết nối với một kết nối đầu ra của một khối giá trị. Khối math_arithmetic (cộng, trừ) là ví dụ về một khối có hai giá trị đầu vào.
  • Đầu vào câu lệnh: Kết nối với kết nối trước đó của khối câu lệnh. Phần lồng nhau của vòng lặp while là một ví dụ về mục nhập câu lệnh.
  • Đầu vào giả: Không có kết nối khối. Hoạt động như một dòng mới khi khối được định cấu hình để sử dụng giá trị đầu vào bên ngoài.
  • Đầu vào hàng cuối: Không có kết nối khối và luôn hoạt động như một dòng mới.

Bạn cũng có thể tạo dữ liệu đầu vào tuỳ chỉnh để hỗ trợ tính năng hiển thị tuỳ chỉnh.

Định dạng JSON và API JavaScript sử dụng các mô hình hơi khác nhau để mô tả dữ liệu đầu vào.

Phương thức nhập và trường trong JSON

Các khối do JSON xác định được cấu trúc dưới dạng chuỗi thông báo nội suy ( message0, message1, ...), trong đó mỗi mã thông báo nội suy (%1, %2, ...) là một trường hoặc đầu vào (do đó trình kết nối đầu vào hiển thị trong thông báo) trong mảng argsN JSON phù hợp. Định dạng này nhằm giúp quốc tế hoá trở nên dễ dàng.

JSON

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

Mã thông báo nội suy phải khớp hoàn toàn với mảng args0: không có nội dung trùng lặp, không bỏ sót. Các mã thông báo có thể xuất hiện theo thứ tự bất kỳ, điều này cho phép nhiều ngôn ngữ thay đổi bố cục của khối.

Văn bản ở một trong hai bên của mã nội suy được cắt bớt. Văn bản sử dụng ký tự % (ví dụ: khi tham chiếu đến tỷ lệ phần trăm) phải sử dụng %% để không được hiểu là mã thông báo nội suy.

Thứ tự của các đối số và loại đối số xác định hình dạng của khối. Việc thay đổi một trong các chuỗi này có thể thay đổi hoàn toàn bố cục của khối. Điều này đặc biệt quan trọng trong các ngôn ngữ có thứ tự từ khác với tiếng Anh. Hãy xem xét một ngôn ngữ giả định, trong đó "set %1 to %2" (như đã sử dụng trong ví dụ ở trên) cần được đảo ngược để nói "put %2 in %1". Việc thay đổi một chuỗi này (và để phần còn lại của JSON không bị ảnh hưởng) sẽ dẫn đến khối sau:

Tự động thay đổi hoàn toàn thứ tự của các trường, tạo đầu vào giả và chuyển từ đầu vào bên ngoài sang đầu vào nội bộ.

Thao tác chặn cũng sẽ tự động thay thế mọi ký tự dòng mới (\n) trong chuỗi thông báo bằng giá trị nhập ở hàng cuối.

JSON

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

Args

Mỗi chuỗi thông báo được ghép nối với một mảng args có cùng số. Ví dụ: message0 đi với args0. Mã thông báo nội suy (%1, %2, ...) đề cập đến các mục của mảng args. Mỗi đối tượng đều có một chuỗi type. Các thông số còn lại sẽ khác nhau tuỳ thuộc vào loại:

Bạn cũng có thể xác định trường tuỳ chỉnhdữ liệu đầu vào tuỳ chỉnh của riêng mình cũng như truyền chúng dưới dạng đối số.

Mỗi đối tượng cũng có thể có trường alt. Trong trường hợp Blockly không nhận ra type của đối tượng, thì đối tượng alt sẽ được sử dụng tại vị trí đó. Ví dụ: nếu một trường mới có tên field_time được thêm vào Blockly, thì các khối sử dụng trường này có thể sử dụng alt để xác định field_input dự phòng cho các phiên bản cũ của 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"
        }
    }
  ]
}

Một đối tượng alt có thể có đối tượng alt riêng, do đó cho phép tạo chuỗi. Cuối cùng, nếu Blockly không thể tạo một đối tượng trong mảng args0 (sau khi thử bất kỳ đối tượng alt nào), thì đối tượng đó sẽ bị bỏ qua.

Dữ liệu đầu vào giả sẽ tự động được thêm vào cuối khối nếu chuỗi message kết thúc bằng văn bản hoặc các trường không có trong dữ liệu đầu vào. Do đó, nếu dữ liệu đầu vào cuối cùng trên một khối là dữ liệu đầu vào giả, thì dữ liệu đó có thể bị bỏ qua khỏi mảng args và không cần nội suy vào message. Việc tự động thêm giá trị nhập giả định danh đánh dấu cho phép người dịch thay đổi message mà không cần sửa đổi phần còn lại của JSON. Hãy xem ví dụ về "set %1 to %2" (không có phương thức nhập giả) và "put %2 in %1" (đã thêm phương thức nhập giả) trên trang này.

implicitAlign0

Trong một số ít trường hợp, đầu vào giả theo sau được tạo tự động cần phải được căn chỉnh với "RIGHT" hoặc "CENTRE". Giá trị mặc định nếu không được chỉ định là "LEFT".

Trong ví dụ bên dưới, message0"send email to %1 subject %2 secure %3" và Blockly sẽ tự động thêm dữ liệu đầu vào giả cho hàng thứ ba. Việc đặt implicitAlign0 thành "RIGHT" sẽ buộc hàng này được căn phải. Sự căn chỉnh này áp dụng cho mọi dữ liệu đầu vào không được xác định rõ trong định nghĩa khối JSON, bao gồm cả dữ liệu đầu vào hàng cuối thay thế các ký tự dòng mới ('\n') trong thông báo. Ngoài ra, còn có một thuộc tính lastDummyAlign0 không dùng nữa cũng có hành vi tương tự như implicitAlign0.

Khi thiết kế khối cho RTL (tiếng Ả Rập và Do Thái), bên trái và bên phải được đảo ngược. Do đó, "RIGHT" sẽ căn chỉnh các trường sang bên trái.

message1, args1, implicitAlign1

Một số khối được chia tự nhiên thành hai hoặc nhiều phần riêng biệt. Hãy xem xét khối lặp lại này có hai hàng:

Nếu khối này được mô tả bằng một thông báo duy nhất, thuộc tính message0 sẽ là "repeat %1 times %2 do %3". Chuỗi này gây khó khăn cho người dịch, rất khó giải thích ý nghĩa của việc thay thế %2. Dữ liệu đầu vào giả %2 cũng có thể không được mong muốn trong một số ngôn ngữ. Và có thể có nhiều khối muốn chia sẻ văn bản của hàng thứ hai. Một phương pháp hay hơn là JSON sử dụng nhiều thuộc tính thông báo và đối số:

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
}

Bạn có thể xác định bất kỳ số lượng thuộc tính message, argsimplicitAlign nào ở định dạng JSON, bắt đầu bằng 0 và tăng dần theo tuần tự. Xin lưu ý rằng Block Factory không thể chia thông điệp thành nhiều phần, nhưng việc này rất đơn giản.

Phương thức nhập và trường trong JavaScript

API JavaScript bao gồm một phương thức append cho từng loại dữ liệu đầu vào:

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

Mỗi phương thức nối có thể nhận một chuỗi giá trị nhận dạng do trình tạo mã sử dụng. Dữ liệu đầu vào giả và hàng cuối hiếm khi cần tham chiếu và giá trị nhận dạng thường không được đặt.

API JavaScript cũng bao gồm một phương thức appendInput chung để thêm dữ liệu đầu vào tuỳ chỉnh. Lưu ý rằng trong trường hợp này, giá trị nhận dạng phải được chuyển trực tiếp đến hàm khởi tạo của mục nhập tuỳ chỉnh.

JavaScript

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

Tất cả phương thức appendInput (cả phương thức chung và không chung) đều trả về đối tượng đầu vào để có thể được định cấu hình thêm bằng cách sử dụng chuỗi phương thức. Có 3 phương thức tích hợp sẵn được dùng để định cấu hình đầu vào.

setCheck

JavaScript

input.setCheck('Number');

Hàm không bắt buộc này dùng để kiểm tra kiểu của các đầu vào đã kết nối. Nếu được cung cấp một đối số có giá trị rỗng, theo mặc định, thì đầu vào này có thể được kết nối với bất kỳ khối nào. Xem phần Kiểm tra loại để biết chi tiết.

setAlign

JavaScript

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

Hàm không bắt buộc này dùng để căn chỉnh các trường (xem bên dưới). Có ba giá trị tự mô tả có thể được truyền dưới dạng đối số cho hàm này: Blockly.inputs.Align.LEFT, Blockly.inputs.Align.RIGHTBlockly.inputs.Align.CENTER.

Khi thiết kế khối cho RTL (tiếng Ả Rập và Do Thái), bên trái và bên phải được đảo ngược. Do đó, Blockly.inputs.Align.RIGHT sẽ căn chỉnh các trường sang bên trái.

appendField

Sau khi tạo và thêm dữ liệu đầu vào vào một khối bằng appendInput, bạn có thể tuỳ ý thêm số trường bất kỳ vào đầu vào đó. Các trường này thường được dùng làm nhãn để mô tả mục đích của từng dữ liệu đầu vào.

JavaScript

input.appendField('hello');

Phần tử trường đơn giản nhất là văn bản. Quy ước của Blockly là sử dụng tất cả văn bản viết thường, ngoại trừ tên riêng (ví dụ: Google, SQL).

Hàng đầu vào có thể chứa số phần tử trường bất kỳ. Nhiều lệnh gọi appendField có thể được liên kết với nhau để thêm nhiều trường vào cùng một hàng đầu vào một cách hiệu quả.

JavaScript

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

Lệnh gọi appendField('hello') thực ra là một lối tắt để sử dụng hàm khởi tạo FieldLabel (Nhãn) rõ ràng: appendField(new Blockly.FieldLabel('hello')). Lần duy nhất bạn muốn sử dụng hàm khởi tạo là khi chỉ định tên lớp để có thể tạo kiểu cho văn bản bằng quy tắc CSS.

Cùng dòng so với bên ngoài

Dữ liệu đầu vào dạng khối có thể hiển thị ở dạng nội bộ hoặc bên ngoài.

Định nghĩa khối có thể chỉ định một giá trị boolean tuỳ chọn kiểm soát đầu vào có cùng dòng hay không. Nếu là false thì mọi giá trị đầu vào đều sẽ là bên ngoài (chẳng hạn như khối bên trái). Nếu là true, thì mọi giá trị đầu vào đều cùng dòng (chẳng hạn như khối bên phải ở trên).

JSON

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

JavaScript

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

Nếu không được xác định, Blockly sẽ sử dụng một số phương pháp phỏng đoán để đoán chế độ nào là tốt nhất. Giả sử Blockly đưa ra lựa chọn đúng, thì bạn nên không xác định trường này vì các bản dịch ngôn ngữ khác nhau có thể tự động có các chế độ khác nhau. Xem ví dụ JSON về "set %1 to %2" (đầu vào bên ngoài) và "put %2 in %1" (đầu vào cùng dòng) trên trang này.

Sử dụng dữ liệu đầu vào cùng dòng khi một khối có khả năng có các dữ liệu đầu vào nhỏ như số. Người dùng có thể bật/tắt tuỳ chọn này thông qua trình đơn theo bối cảnh nếu cấu hình collapse đang bật (giá trị mặc định là true nếu hộp công cụ có các danh mục).

Các trường

Các trường xác định phần lớn các thành phần trên giao diện người dùng trong một khối. Các nhãn này bao gồm các nhãn chuỗi, hình ảnh và dữ liệu đầu vào cho dữ liệu chữ, chẳng hạn như các chuỗi và số. Ví dụ đơn giản nhất là khối math_number, sử dụng field_input để cho phép người dùng nhập một số.

Các trường được thêm vào khối bằng cách sử dụng appendField.

Blockly cung cấp một số trường tích hợp sẵn, bao gồm cả dữ liệu nhập văn bản, công cụ chọn màu và hình ảnh. Bạn cũng có thể tạo các trường của riêng mình.

→ Thông tin thêm về các trường tích hợp sẵn.

→ Thông tin thêm về cách tạo trường tuỳ chỉnh.

Biểu tượng

Các biểu tượng xác định các thành phần trên giao diện người dùng trên một khối hiển thị thông tin "meta" về khối đó.

Các biểu tượng được thêm vào khối bằng addIcon.

Blockly cung cấp một số biểu tượng tích hợp sẵn, bao gồm cả biểu tượng nhận xét và biểu tượng cảnh báo. Bạn cũng có thể tạo các biểu tượng của riêng mình.

→ Thông tin thêm về cách tạo biểu tượng tuỳ chỉnh.

Chú thích

Chú giải công cụ cung cấp trợ giúp tức thì khi người dùng di chuột qua khối. Nếu văn bản dài, văn bản sẽ tự động xuống dòng.

JSON

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

JavaScript

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

Trong API JavaScript, chú giải công cụ cũng có thể được xác định là một hàm thay vì một chuỗi tĩnh. Điều này cho phép trợ giúp động. Hãy xem math_arithmetic để biết ví dụ về chú giải công cụ sẽ thay đổi tuỳ thuộc vào tuỳ chọn trình đơn thả xuống đã được chọn.

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

Khi sử dụng API JavaScript, các khối có thể chỉ định một hàm, thay vì một chuỗi tĩnh (trả về chuỗi chú giải công cụ). Cách này cho phép hiển thị chú giải công cụ động. Hãy xem math_arithmetic để biết ví dụ.

Tùy chỉnh theo yêu cầu

Bạn cũng có thể tuỳ chỉnh giao diện của phần chú thích bằng cách cung cấp một hàm hiển thị tuỳ chỉnh. Tạo một hàm chấp nhận 2 tham số:

  • đầu tiên là phần tử <div> nơi bạn sẽ kết xuất nội dung
  • thứ hai, là phần tử thực tế mà bạn di chuột qua và bạn sẽ hiển thị chú giải công cụ cho

Trong phần nội dung của hàm, bạn có thể hiển thị bất kỳ nội dung nào mình muốn trên div. Để nhận chuỗi chú giải công cụ được xác định trên khối mà bạn di chuột qua, bạn có thể gọi Blockly.Tooltip.getTooltipOfObject(element);, trong đó element là tham số thứ hai ở trên.

Cuối cùng, hãy đăng ký hàm này để Blockly có thể gọi vào thời điểm thích hợp:

Blockly.Tooltip.setCustomTooltip(yourFnHere);

Để xem ví dụ, vui lòng xem Bản minh hoạ Chú giải công cụ tuỳ chỉnh.

URL trợ giúp

Bạn có thể liên kết với trang trợ giúp về các quy tắc chặn. Để sử dụng tính năng này, người dùng có thể sử dụng tính năng Blockly cho web bằng cách nhấp chuột phải vào khối rồi chọn "Help" (Trợ giúp) trên trình đơn theo bối cảnh. Nếu giá trị này là null thì trình đơn sẽ có màu xám.

JSON

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

JavaScript

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

Khi sử dụng API JavaScript, các khối có thể chỉ định một hàm, thay vì một chuỗi tĩnh (sẽ trả về một chuỗi URL), nhờ đó cho phép trợ giúp động.

Thay đổi trình nghe và trình xác thực

Các khối có thể có các chức năng trình nghe thay đổi được gọi khi có bất kỳ thay đổi nào đối với không gian làm việc (bao gồm cả những thay đổi không liên quan đến quy tắc chặn). Những thông báo này chủ yếu được dùng để đặt văn bản cảnh báo của quy tắc chặn hoặc thông báo tương tự dành cho người dùng bên ngoài không gian làm việc.

Hàm này được thêm bằng cách gọi setOnChange bằng một hàm và bạn có thể thực hiện việc này trong quá trình khởi tạo hoặc thông qua phần mở rộng JSON nếu bạn định sử dụng hàm này trên tất cả nền tảng.

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

Hệ thống sẽ gọi hàm này, truyền vào sự kiện thay đổi. Bên trong hàm này, this tham chiếu đến thực thể của khối.

Vì hàm này được gọi khi có bất kỳ thay đổi nào, nên nếu được sử dụng, nhà phát triển phải đảm bảo trình nghe chạy nhanh. Bạn cũng nên cảnh giác với những thay đổi đối với không gian làm việc có thể chuyển tầng hoặc vòng lặp trở lại trình nghe.

Hãy xem ví dụ về các khối controls_flow_statements, logic_compareprocedures_ifreturn.

Xin lưu ý rằng các trường có thể chỉnh sửa có trình nghe sự kiện riêng để xác thực dữ liệu đầu vào và gây ra hiệu ứng phụ.

Bộ biến đổi

Các bộ biến đổi cho phép các khối nâng cao thay đổi hình dạng, đáng chú ý nhất là do người dùng mở hộp thoại để thêm, xoá hoặc sắp xếp lại các thành phần. Bạn có thể thêm trình đột biến thông qua JSON bằng khoá mutator.

JSON

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

Cấu hình mỗi khối

Các thực thể khối có một số thuộc tính định cấu hình cách chúng hoạt động với người dùng. Bạn có thể dùng chúng để ràng buộc không gian làm việc nhằm phản ánh một số thuộc tính nhất định của miền (ví dụ: chỉ có một sự kiện "bắt đầu") hoặc tập trung vào nỗ lực của người dùng (ví dụ: hướng dẫn).

Trạng thái có thể xoá

block.setDeletable(false);

Khi bạn đặt chính sách này thành false, người dùng sẽ không thể xoá khối. Chặn theo mặc định thành có thể xoá trên không gian làm việc có thể chỉnh sửa.

Bất kỳ khối nào (ngay cả khối không thể chọn) đều có thể bị xoá theo phương thức lập trình:

block.dispose();

Trạng thái có thể chỉnh sửa

block.setEditable(false);

Khi bạn đặt thành false (sai), người dùng sẽ không thể thay đổi các trường của khối (ví dụ: trình đơn thả xuống và dữ liệu nhập bằng văn bản). Chặn chế độ mặc định thành có thể chỉnh sửa trên không gian làm việc có thể chỉnh sửa.

Trạng thái có thể di chuyển

block.setMovable(false);

Khi bạn đặt chính sách này thành false, người dùng sẽ không thể trực tiếp di chuyển khối. Một khối bất động là con của một khối khác có thể không bị ngắt kết nối khỏi khối đó, mặc dù khối này sẽ di chuyển cùng với thành phần mẹ nếu khối mẹ di chuyển. Theo mặc định, các tuỳ chọn chặn là có thể di chuyển trên không gian làm việc có thể chỉnh sửa.

Bất kỳ khối nào (kể cả khối bất động sản) đều có thể được di chuyển bằng phương pháp lập trình khi đã xuất hiện trên không gian làm việc.

block.moveBy(dx, dy)

Vị trí bắt đầu của một khối trên không gian làm việc mặc định là (0, 0).

Chặn dữ liệu

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

Dữ liệu là một chuỗi không bắt buộc và tuỳ ý được đính kèm với khối. Khi khối được chuyển đổi tuần tự, chuỗi dữ liệu sẽ được chuyển đổi tuần tự cùng với khối đó. Điều này bao gồm cả thời điểm khối được sao chép hoặc sao chép/dán.

Thông thường, thuộc tính này được dùng để liên kết một khối với tài nguyên bên ngoài.

Khi được chuyển đổi tuần tự thành JSON, dữ liệu sẽ được lưu trữ dưới dạng thuộc tính cấp cao nhất trong khối:

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

Khi được chuyển đổi tuần tự thành XML (hệ thống chuyển đổi tuần tự đóng gói cũ), chuỗi dữ liệu sẽ được lưu trữ trong thẻ <data></data> bên trong khối:

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

Phá huỷ

Các khối có hook destroy, được gọi khi bị xoá khỏi không gian làm việc. Bạn có thể dùng lớp này để huỷ mọi mô hình dữ liệu sao lưu/tài nguyên bên ngoài liên kết với khối không còn cần thiết nữa.

JSON

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

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

JavaScript

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

Phương thức destroy được gọi sau khi phần tử mẹ của khối đã bị huỷ bỏ, nhưng trước khi bất kỳ phần tử con hoặc trường nào của khối đó đã bị huỷ bỏ.

Trình đơn ngữ cảnh

Theo mặc định, các khối có trình đơn theo bối cảnh nhấp chuột phải cho phép người dùng thực hiện các thao tác như thêm nhận xét hoặc sao chép khối.

Bạn có thể tắt trình đơn theo bối cảnh của một khối riêng lẻ bằng cách thực hiện:

block.contextMenu = false;

Bạn cũng có thể tuỳ chỉnh các lựa chọn hiển thị trong trình đơn. Để tuỳ chỉnh trình đơn cho tất cả các khối, hãy tham khảo tài liệu về trình đơn theo bối cảnh. Để tuỳ chỉnh trình đơn cho một khối riêng lẻ, bạn có thể triển khai customContextMenu. Hàm này lấy một loạt các tuỳ chọn trên trình đơn và sửa đổi tại chỗ, nghĩa là bạn có thể thêm và xoá các mục.

Mỗi tuỳ chọn trình đơn là một đối tượng có ba thuộc tính:

  • text là văn bản hiển thị.
  • enabled là một giá trị boolean. Khi tắt, tuỳ chọn này sẽ hiển thị với văn bản màu xám.
  • callback là hàm sẽ được gọi khi người dùng nhấp vào tuỳ chọn này.