Ekstensi adalah fungsi yang berjalan di setiap blok jenis tertentu karena blok dibuat. Hal ini sering kali menambahkan beberapa konfigurasi atau perilaku kustom ke blok.
Mutator adalah jenis ekstensi khusus yang menambahkan serialisasi kustom, dan terkadang UI, ke blok.
Ekstensi
Ekstensi adalah fungsi yang berjalan di setiap blok jenis tertentu karena blok dibuat. Mereka dapat menambahkan konfigurasi khusus (mis. menyetel tooltip blok) atau perilaku kustom (misalnya, menambahkan pemroses peristiwa ke blok).
// 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;
});
});
Ekstensi harus "didaftarkan" sehingga mereka dapat dikaitkan dengan suatu
tombol. Selanjutnya, Anda dapat menetapkan kunci string ini ke properti extensions
JSON jenis pemblokiran
definisi untuk menerapkan
ekstensi ke blok tersebut.
{
//...,
"extensions": ["parent_tooltip_extension",]
}
Anda juga dapat menambahkan beberapa ekstensi sekaligus. Perhatikan bahwa extensions
harus berupa array, meskipun Anda hanya menerapkan satu ekstensi.
{
//...,
"extensions": ["parent_tooltip_extension", "break_warning_extension"],
}
Mixin
Blockly juga menyediakan metode praktis untuk situasi saat Anda ingin menambahkan beberapa properti/fungsi helper ke blok, tetapi tidak menjalankannya secara langsung. Ini dengan memungkinkan Anda mendaftarkan mixin yang berisi semua properti/metode tambahan. Objek mixin kemudian dibungkus dalam fungsi yang menerapkan {i> mixin<i} setiap kali sebuah instance jenis blok yang ditentukan dibuat.
Blockly.Extensions.registerMixin('my_mixin', {
someProperty: 'a cool value',
someMethod: function() {
// Do something cool!
}
))`
Kunci string yang terkait dengan mixin dapat direferensikan di JSON seperti yang lainnya .
{
//...,
"extensions": ["my_mixin"],
}
Mutator
Mutator adalah jenis ekstensi khusus yang
menambahkan serialisasi ekstra (ekstra
yang disimpan dan dimuat) ke sebuah blok. Misalnya, {i>built-in<i}
Blok controls_if
dan list_create_with
memerlukan serialisasi tambahan sehingga
mereka bisa menyimpan
berapa banyak input yang mereka miliki.
Perhatikan bahwa mengubah bentuk blok tidak selalu berarti Anda perlu
serialisasi tambahan. Misalnya, blok math_number_property
mengubah
{i>shape<i}, tetapi hal itu dilakukan berdasarkan {i>field<i} {i>dropdown<i}, yang nilainya sudah didapatkan
diserialisasi. Dengan demikian, instance tersebut dapat menggunakan kolom
validator, dan tidak
memerlukan mutator.
Lihat serialisasi halaman untuk informasi selengkapnya tentang kapan Anda memerlukan mutator dan tidak.
Mutator juga menyediakan UI bawaan bagi pengguna untuk mengubah bentuk blok jika Anda menyediakan beberapa metode opsional.
Hook serialisasi
Mutator memiliki dua pasang hook serialisasi yang digunakan. Sepasang hook berfungsi dengan sistem serialisasi JSON yang baru, sedangkan pasangan lainnya berfungsi dengan sistem serialisasi XML lama. Anda harus memberikan setidaknya salah satu dari pasangan data tersebut.
saveExtraState dan loadExtraState
saveExtraState
dan loadExtraState
adalah hook serialisasi yang berfungsi dengan
sistem serialisasi JSON yang baru. saveExtraState
menampilkan JSON yang dapat diserialisasi
nilai yang mewakili status tambahan blok, dan loadExtraState
menerima nilai serialisabel JSON yang sama, dan menerapkannya ke blok.
// 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 yang dihasilkan akan terlihat seperti:
{
"type": "lists_create_with",
"extraState": {
"itemCount": 3 // or whatever the count is
}
}
Tanpa status
Jika blok Anda berada dalam status {i>default<i} saat diserialisasi, maka
Metode saveExtraState
dapat menampilkan null
untuk menunjukkannya. Jika
Metode saveExtraState
menampilkan null
, lalu tidak ada properti extraState
yang ditambahkan ke
JSON. Tindakan ini menjaga ukuran file yang disimpan tetap kecil.
Serialisasi lengkap dan data cadangan
saveExtraState
juga menerima parameter doFullSerialization
opsional. Ini
digunakan oleh blok yang mereferensikan status yang diserialisasi oleh
serializer (seperti model data pendukung). Parameter tersebut menandakan bahwa
status yang direferensikan tidak akan tersedia ketika blok dideserialisasi, sehingga
harus melakukan serialisasi semua status cadangannya. Sebagai contoh, ini adalah
{i>true<i} ketika blok individual diserialisasi, atau ketika suatu blok disalin-tempel.
Dua kasus penggunaan umum untuk hal ini adalah:
- Saat blok individual dimuat ke ruang kerja tempat data pendukung model tidak ada, terdapat cukup informasi dalam statusnya sendiri untuk membuat model data baru.
- Jika suatu blok disalin dan ditempel, blok tersebut akan selalu membuat pendukung baru alih-alih mereferensikan model yang sudah ada.
Beberapa blok yang menggunakan
ini adalah
Blok @blockly/block-shareable-procedures. Biasanya
mereka membuat serial referensi ke model data pendukung, yang menyimpan statusnya.
Namun, jika parameter doFullSerialization
benar, parameter tersebut akan menserialisasi semua
status mereka. Blok prosedur yang dapat dibagikan
menggunakan ini untuk memastikan bahwa ketika
menyalin dan menempel, mereka membuat model
data pendukung baru, alih-alih mereferensikan
model yang sudah ada.
mutationToDom dan domToMutation
mutationToDom
dan domToMutation
adalah hook serialisasi yang berfungsi dengan
sistem serialisasi XML lama. Gunakan hook ini hanya jika perlu (misalnya, Anda
mengerjakan basis kode lama yang belum bermigrasi), jika tidak, gunakan
saveExtraState
dan loadExtraState
.
mutationToDom
menampilkan node XML yang mewakili status tambahan
, dan domToMutation
menerima node XML yang sama dan menerapkan status ke
blok tersebut.
// 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 yang dihasilkan akan terlihat seperti:
<block type="lists_create_with">
<mutation items="3"></mutation>
</block>
Jika fungsi mutationToDom
menampilkan null, tidak ada elemen tambahan yang akan
ditambahkan ke XML.
Hook UI
Jika Anda menyediakan fungsi tertentu sebagai bagian dari mutator, Blockly akan menambahkan "mutator" default UI ke blok Anda.
Anda tidak perlu menggunakan UI ini jika ingin menambahkan serialisasi ekstra. Anda dapat gunakan UI khusus, seperti blok-plus-minus plugin atau Anda tidak bisa menggunakan UI sama sekali.
tulis dan uraikan
UI default bergantung pada fungsi compose
dan decompose
.
decompose
"meledak" blok menjadi sub-blok yang lebih
kecil yang dapat dipindahkan
ada, ditambahkan, dan dihapus. Fungsi ini akan menampilkan "blok atas" yang merupakan
blok utama di ruang kerja mutator
yang terhubung dengan sub-blok.
compose
kemudian menafsirkan konfigurasi sub-blok dan menggunakannya untuk
mengubah blok utama. Fungsi ini harus menerima "blok atas" yang merupakan
yang ditampilkan oleh decompose
sebagai parameter.
Perlu diingat bahwa fungsi ini akan "tercampur dalam" ke blok yang "dimutated" jadi this
dapat digunakan untuk merujuk
ke blok tersebut.
// 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
Atau, Anda juga dapat menentukan fungsi saveConnections
yang berfungsi dengan
UI default. Fungsi ini memberi Anda kesempatan untuk mengaitkan turunan
blok utama (yang ada di ruang kerja utama) dengan sub-blok yang ada di
ruang kerja mutator Anda. Anda kemudian dapat menggunakan data ini untuk memastikan compose
berfungsi menghubungkan ulang turunan blok utama dengan benar
sub-blok diatur ulang.
saveConnections
harus menerima "blok atas" dikembalikan oleh decompose
Anda
berfungsi sebagai parameter. Jika fungsi saveConnections
ditentukan, Blockly
akan memanggilnya sebelum memanggil 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();
}
},
Mendaftarkan
Mutator hanyalah jenis ekstensi khusus, jadi mereka juga harus terdaftar sebelum Anda dapat menggunakannya di JSON jenis pemblokiran definisinya.
// 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
: String yang akan dikaitkan dengan mutator sehingga Anda dapat menggunakannya di JSON.mixinObj
: Objek yang berisi berbagai metode mutasi. Mis.saveExtraState
danloadExtraState
.opt_helperFn
: Fungsi bantuan opsional yang akan berjalan di blok setelah {i> mixin<i} dicampur.opt_blockList
: Array opsional dari jenis blok (sebagai string) yang akan ditambahkan ke flyout di UI mutator default, jika metode UI juga didefinisikan.
Perlu diperhatikan bahwa tidak seperti ekstensi, setiap jenis blok mungkin hanya memiliki satu mutator.
{
//...
"mutator": "controls_if_mutator"
}
Fungsi bantuan
Bersama dengan mixin, mutator dapat mendaftarkan fungsi bantuan. Fungsi ini adalah berjalan pada setiap blok dari tipe yang diberikan setelah itu dibuat dan mixinObj akan ditambahkan. Dapat digunakan untuk menambahkan pemicu atau efek tambahan ke mutasi.
Misalnya, Anda bisa menambahkan bantuan ke blok seperti daftar yang menyetel jumlah awal item:
var helper = function() {
this.itemCount_ = 5;
this.updateShape();
}