Phần mở rộng là các hàm chạy trên mỗi khối thuộc một loại cho trước vì khối này đã tạo. Các khối này thường thêm một số cấu hình hoặc hành vi tuỳ chỉnh vào khối.
Biến đổi là một loại tiện ích đặc biệt thêm chuyển đổi tuần tự tuỳ chỉnh và thành một khối.
Phần mở rộng
Phần mở rộng là các hàm chạy trên mỗi khối thuộc một loại cho trước vì khối này đã tạo. Họ có thể thêm cấu hình tuỳ chỉnh (ví dụ: đặt phần chú thích của quy tắc chặn) hoặc hành vi tuỳ chỉnh (ví dụ: thêm một trình nghe sự kiện vào khối).
// This extension sets the block's tooltip to be a function which displays
// the parent block's tooltip (if it exists).
Blockly.Extensions.register(
'parent_tooltip_extension',
function() { // this refers to the block that the extension is being run on
var thisBlock = this;
this.setTooltip(function() {
var parent = thisBlock.getParent();
return (parent && parent.getInputsInline() && parent.tooltip) ||
Blockly.Msg.MATH_NUMBER_TOOLTIP;
});
});
Tiện ích phải được "đăng ký" để chúng có thể liên kết với một chuỗi
. Sau đó, bạn có thể chỉ định khoá chuỗi này cho thuộc tính extensions
của
JSON của loại khối
xác định để áp dụng
tiện ích mở rộng cho khối.
{
//...,
"extensions": ["parent_tooltip_extension",]
}
Bạn cũng có thể thêm nhiều phần mở rộng cùng một lúc. Xin lưu ý rằng extensions
thuộc tính phải là một mảng, ngay cả khi bạn chỉ áp dụng một phần mở rộng.
{
//...,
"extensions": ["parent_tooltip_extension", "break_warning_extension"],
}
Mixin (Nhạc kết hợp)
Blockly cũng cung cấp một phương thức thuận tiện cho các trường hợp mà bạn muốn thêm một số thuộc tính/hàm trợ giúp vào một khối, nhưng không chạy chúng ngay lập tức. Chiến dịch này hoạt động bằng cách cho phép bạn đăng ký một sản phẩm hỗn hợp chứa tất cả các thuộc tính/phương thức bổ sung của bạn. Đối tượng trộn sau đó được bao bọc trong một hàm áp dụng trộn mỗi khi một thực thể của loại khối đã cho sẽ được tạo.
Blockly.Extensions.registerMixin('my_mixin', {
someProperty: 'a cool value',
someMethod: function() {
// Do something cool!
}
))`
Khoá chuỗi liên kết với trình kết hợp có thể được tham chiếu trong JSON giống như bất kỳ khoá nào khác tiện ích.
{
//...,
"extensions": ["my_mixin"],
}
Biến thể
Biến đổi (mutator) là một loại tiện ích mở rộng đặc biệt bổ sung thêm chuỗi tuần tự (thêm
được lưu và tải) vào một khối. Ví dụ: tham số tích hợp
Các khối controls_if
và list_create_with
cần thêm quá trình chuyển đổi tuần tự để
chúng có thể lưu số lượng
đầu vào mà họ có.
Lưu ý rằng việc thay đổi hình dạng khối không nhất thiết có nghĩa là bạn cần
chuyển đổi tuần tự bổ sung. Ví dụ: khối math_number_property
thay đổi
nhưng nó thực hiện việc đó dựa trên trường thả xuống, có giá trị đã được nhận
đã chuyển đổi tuần tự. Như vậy, nó chỉ có thể sử dụng trường
trình xác thực và không
cần một người biến đổi.
Xem chuyển đổi tuần tự cho thêm thông tin về thời điểm bạn cần và khi nào không cần biến thể.
Trình đột biến cũng cung cấp một giao diện người dùng tích hợp sẵn để người dùng thay đổi hình dạng của khối nếu bạn cung cấp một số phương thức tuỳ chọn.
Móc chuyển đổi tuần tự
Các đột biến có 2 cặp nối tiếp nối tuần tự mà chúng hoạt động. Một cặp móc hoạt động với hệ thống chuyển đổi tuần tự JSON mới, còn cặp còn lại hoạt động với hệ thống chuyển đổi tuần tự XML cũ. Bạn phải cung cấp ít nhất một trong các cặp này.
save ExtraState và loadExtraState
saveExtraState
và loadExtraState
là các hook chuyển đổi tuần tự hoạt động với
hệ thống chuyển đổi tuần tự JSON mới. saveExtraState
trả về một tệp JSON có thể chuyển đổi tuần tự
giá trị đại diện cho trạng thái bổ sung của khối và loadExtraState
chấp nhận cùng một giá trị JSON có thể chuyển đổi tuần tự và áp dụng giá trị đó cho khối.
// These are the serialization hooks for the lists_create_with block.
saveExtraState: function() {
return {
'itemCount': this.itemCount_,
};
},
loadExtraState: function(state) {
this.itemCount_ = state['itemCount'];
// This is a helper function which adds or removes inputs from the block.
this.updateShape_();
},
JSON thu được sẽ có dạng như sau:
{
"type": "lists_create_with",
"extraState": {
"itemCount": 3 // or whatever the count is
}
}
Không có tiểu bang nào
Nếu khối của bạn ở trạng thái mặc định khi được chuyển đổi tuần tự, thì
Phương thức saveExtraState
có thể trả về null
để cho biết điều này. Nếu
Phương thức saveExtraState
trả về null
, sau đó không thêm thuộc tính extraState
nào vào
JSON. Thao tác này giúp giảm kích thước tệp bạn lưu.
Dữ liệu sao lưu và chuyển đổi tuần tự đầy đủ
saveExtraState
cũng nhận được một tham số doFullSerialization
(không bắt buộc). Chiến dịch này
được sử dụng bởi các khối tham chiếu trạng thái tham chiếu được chuyển đổi tuần tự bởi
trình chuyển đổi tuần tự (như mô hình dữ liệu sao lưu). Thông số này báo hiệu rằng
trạng thái được tham chiếu sẽ không có sẵn khi khối được giải tuần tự, vì vậy
phải chuyển đổi tuần tự tất cả trạng thái sao lưu. Ví dụ: đây là
true khi một khối riêng lẻ được chuyển đổi tuần tự hoặc khi một khối được sao chép và dán.
Có hai trường hợp sử dụng phổ biến cho vấn đề này:
- Khi một khối riêng lẻ được tải vào một không gian làm việc nơi dữ liệu sao lưu mô hình này không tồn tại, mô hình này có đủ thông tin ở trạng thái riêng để để tạo một mô hình dữ liệu mới.
- Khi được sao chép, một khối luôn tạo ra một bản sao lưu mới thay vì tham chiếu một mô hình dữ liệu hiện có.
Một số khối sử dụng lệnh này là
@blockly/block-shareable-procedures. Bình thường
chúng tuần tự hoá tham chiếu đến mô hình dữ liệu sao lưu. Mô hình này lưu trữ trạng thái của chúng.
Tuy nhiên, nếu tham số doFullSerialization
là true, thì chúng sẽ chuyển đổi tuần tự tất cả
trạng thái của chúng. Các khối quy trình có thể chia sẻ sử dụng đoạn mã này để đảm bảo rằng khi chúng
được sao chép và dán, chúng sẽ tạo một mô hình dữ liệu sao lưu mới, thay vì tham chiếu
mô hình hiện tại.
mutationToDom và domToMutation
mutationToDom
và domToMutation
là các hook chuyển đổi tuần tự hoạt động với
hệ thống chuyển đổi tuần tự XML cũ. Chỉ sử dụng những nội dung hấp dẫn này nếu cần (ví dụ: bạn
hoạt động trên một cơ sở mã cũ chưa được di chuyển), nếu không, hãy sử dụng
saveExtraState
và loadExtraState
.
mutationToDom
trả về một nút XML đại diện cho trạng thái bổ sung của
khối và domToMutation
chấp nhận cùng một nút XML đó và áp dụng trạng thái cho
khối.
// These are the old XML serialization hooks for the lists_create_with block.
mutationToDom: function() {
// You *must* create a <mutation></mutation> element.
// This element can have children.
var container = Blockly.utils.xml.createElement('mutation');
container.setAttribute('items', this.itemCount_);
return container;
},
domToMutation: function(xmlElement) {
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
// This is a helper function which adds or removes inputs from the block.
this.updateShape_();
},
XML thu được sẽ có dạng như sau:
<block type="lists_create_with">
<mutation items="3"></mutation>
</block>
Nếu hàm mutationToDom
trả về giá trị rỗng, thì sẽ không có phần tử bổ sung nào được
được thêm vào XML.
Hook giao diện người dùng
Nếu bạn cung cấp một số hàm nhất định như một phần của trình biến đổi, Blockly sẽ thêm "người biến đổi" mặc định Giao diện người dùng vào khối của bạn.
Bạn không cần phải sử dụng giao diện người dùng này nếu muốn thêm chuyển đổi tuần tự bổ sung. Bạn có thể sử dụng giao diện người dùng tuỳ chỉnh, như các khối-dấu cộng-trừ trình bổ trợ hoặc bạn có thể không sử dụng giao diện người dùng nào!
soạn và phân tách
Giao diện người dùng mặc định dựa trên các hàm compose
và decompose
.
decompose
"nổ" thành các khối con nhỏ hơn có thể được di chuyển
xung quanh, đã thêm và bị xoá. Hàm này phải trả về một "khối trên cùng" tức là
khối chính trong không gian làm việc của trình biến đổi mà các khối phụ kết nối.
Sau đó, compose
sẽ diễn giải cấu hình của các khối phụ và sử dụng chúng để
sửa đổi khối chính. Hàm này phải chấp nhận "khối trên cùng" đó là
được decompose
trả về dưới dạng tham số.
Lưu ý rằng các hàm này được "kết hợp" thành khối bị "thay đổi" nên this
có thể được dùng để tham chiếu đến khối đó.
// These are the decompose and compose functions for the lists_create_with block.
decompose: function(workspace) {
// This is a special sub-block that only gets created in the mutator UI.
// It acts as our "top block"
var topBlock = workspace.newBlock('lists_create_with_container');
topBlock.initSvg();
// Then we add one sub-block for each item in the list.
var connection = topBlock.getInput('STACK').connection;
for (var i = 0; i < this.itemCount_; i++) {
var itemBlock = workspace.newBlock('lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;
}
// And finally we have to return the top-block.
return topBlock;
},
// The container block is the top-block returned by decompose.
compose: function(topBlock) {
// First we get the first sub-block (which represents an input on our main block).
var itemBlock = topBlock.getInputTargetBlock('STACK');
// Then we collect up all of the connections of on our main block that are
// referenced by our sub-blocks.
// This relates to the saveConnections hook (explained below).
var connections = [];
while (itemBlock && !itemBlock.isInsertionMarker()) { // Ignore insertion markers!
connections.push(itemBlock.valueConnection_);
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
// Then we disconnect any children where the sub-block associated with that
// child has been deleted/removed from the stack.
for (var i = 0; i < this.itemCount_; i++) {
var connection = this.getInput('ADD' + i).connection.targetConnection;
if (connection && connections.indexOf(connection) == -1) {
connection.disconnect();
}
}
// Then we update the shape of our block (removing or adding iputs as necessary).
// `this` refers to the main block.
this.itemCount_ = connections.length;
this.updateShape_();
// And finally we reconnect any child blocks.
for (var i = 0; i < this.itemCount_; i++) {
connections[i].reconnect(this, 'ADD' + i);
}
},
saveConnections
Nếu muốn, bạn cũng có thể xác định hàm saveConnections
hoạt động với
giao diện người dùng mặc định. Hàm này cho phép bạn liên kết các phần tử con của
khối chính (tồn tại trên không gian làm việc chính) có các khối phụ tồn tại trong
không gian làm việc của đối tượng biến đổi. Sau đó, bạn có thể dùng dữ liệu này để đảm bảo compose
của mình
sẽ kết nối lại các phần tử con của khối chính đúng cách khi
các khối phụ được sắp xếp lại.
saveConnections
phải chấp nhận "khối trên cùng" do decompose
của bạn trả về
dưới dạng tham số. Nếu hàm saveConnections
được định nghĩa, thì Blockly
sẽ gọi hàm này trước khi gọi compose
.
saveConnections: function(topBlock) {
// First we get the first sub-block (which represents an input on our main block).
var itemBlock = topBlock.getInputTargetBlock('STACK');
// Then we go through and assign references to connections on our main block
// (input.connection.targetConnection) to properties on our sub blocks
// (itemBlock.valueConnection_).
var i = 0;
while (itemBlock) {
// `this` refers to the main block (which is being "mutated").
var input = this.getInput('ADD' + i);
// This is the important line of this function!
itemBlock.valueConnection_ = input && input.connection.targetConnection;
i++;
itemBlock = itemBlock.nextConnection &&
itemBlock.nextConnection.targetBlock();
}
},
Đang đăng ký
Đột biến chỉ là một loại tiện ích mở rộng đặc biệt, do đó chúng cũng phải đã được đăng ký trước khi có thể sử dụng chúng trong tệp JSON của loại khối định nghĩa.
// Function signature.
Blockly.Extensions.registerMutator(name, mixinObj, opt_helperFn, opt_blockList);
// Example call.
Blockly.Extensions.registerMutator(
'controls_if_mutator',
{ /* mutator methods */ },
undefined,
['controls_if_elseif', 'controls_if_else']);
name
: Một chuỗi liên kết với biến đổi để bạn có thể sử dụng trong JSON.mixinObj
: Một đối tượng chứa nhiều phương thức đột biến. Ví dụ:saveExtraState
vàloadExtraState
.opt_helperFn
: Một hàm trợ giúp không bắt buộc sẽ chạy trên khối sau khi trộn.opt_blockList
: Một mảng các loại khối tuỳ chọn (dưới dạng chuỗi) sẽ được được thêm vào trình đơn hiển thị trong giao diện người dùng biến đổi mặc định, nếu các phương thức giao diện người dùng cũng xác định.
Lưu ý rằng không giống như tiện ích, mỗi loại khối có thể chỉ có một biến đổi.
{
//...
"mutator": "controls_if_mutator"
}
Chức năng trợ giúp
Cùng với Mixin, một biến đổi (mutator) có thể đăng ký một hàm trợ giúp. Chức năng này chạy trên mỗi khối thuộc loại đã cho sau khi được tạo và MixinObj được đã thêm. Nó có thể được dùng để thêm các yếu tố kích hoạt hoặc hiệu ứng khác vào một đột biến.
Ví dụ: bạn có thể thêm một trình trợ giúp vào khối giống như danh sách để thiết lập số mục ban đầu:
var helper = function() {
this.itemCount_ = 5;
this.updateShape();
}