Erweiterungen sind Funktionen, die in jedem Block eines bestimmten Typs ausgeführt werden, wenn der Block erstellt. Dadurch werden häufig benutzerdefinierte Konfigurationen oder Funktionsweisen zu einem Block hinzugefügt.
Ein Mutator ist eine spezielle Erweiterung, die eine benutzerdefinierte Serialisierung hinzufügt. bis hin zu einem Block.
Erweiterungen
Erweiterungen sind Funktionen, die in jedem Block eines bestimmten Typs ausgeführt werden, wenn der Block erstellt. Sie können eine benutzerdefinierte Konfiguration hinzufügen (z.B. durch Festlegen der Kurzinfo der Blockierung) oder benutzerdefiniertes Verhalten (z.B. Hinzufügen eines Event-Listeners zum Block).
// 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;
});
});
Erweiterungen müssen „registriert“ sein damit sie mit einem String
. Dann können Sie diesen Stringschlüssel dem Attribut extensions
Ihres
JSON des Blocktyps
die Definition für die
Erweiterung hinzu.
{
//...,
"extensions": ["parent_tooltip_extension",]
}
Sie können auch mehrere Erweiterungen gleichzeitig hinzufügen. Beachten Sie, dass die extensions
Property muss ein Array sein, auch wenn Sie nur eine Erweiterung anwenden.
{
//...,
"extensions": ["parent_tooltip_extension", "break_warning_extension"],
}
Mixins
Blockly bietet auch eine praktische Methode, wenn Sie einige Eigenschaften/Hilfsfunktionen zu einem Block hinzufügen, aber nicht sofort ausführen. Dieses ermöglicht die Registrierung eines Mixin -Objekt, das all Ihre zusätzlichen Eigenschaften/Methoden enthält. Das Mixin-Objekt wird dann in eine Funktion eingeschlossen, die das Mixin jedes Mal anwendet, wenn eine Instanz von der angegebene Blocktyp erstellt wird.
Blockly.Extensions.registerMixin('my_mixin', {
someProperty: 'a cool value',
someMethod: function() {
// Do something cool!
}
))`
Auf Stringschlüssel, die mit Mixins verknüpft sind, kann in JSON genau wie auf jeden anderen String verwiesen werden .
{
//...,
"extensions": ["my_mixin"],
}
Mutatoren
Ein Mutator ist eine spezielle Erweiterung, die eine zusätzliche Serialisierung (zusätzliche
gespeichert und geladen) in einen Block. Zum Beispiel die integrierte
Die Blöcke controls_if
und list_create_with
benötigen eine zusätzliche Serialisierung, damit
wie viele Eingaben sie speichern können.
Wenn Sie die Form eines Blocks ändern, bedeutet das nicht unbedingt, dass
zusätzliche Serialisierung. Beispielsweise ändert sich der math_number_property
-Block
und zwar mithilfe eines Dropdown-Felds, dessen Wert bereits
serialisiert. Daher kann einfach ein Feld
Validator und nicht
brauchen einen Mutator.
Weitere Informationen finden Sie im Abschnitt zur Serialisierung für wann Sie einen Mutator benötigen und wann nicht.
Mutatoren bieten auch eine integrierte Benutzeroberfläche, über die Nutzende die Form von Blöcken ändern können, wenn stellen Sie einige optionale Methoden bereit.
Serialisierungs-Hooks
Mutatoren haben zwei Serialisierungs-Hook-Paare, mit denen sie arbeiten. Ein Paar Haken funktioniert mit dem neuen JSON-Serialisierungssystem, während das andere Paar mit dem ein altes XML-Serialisierungssystem. Sie müssen mindestens eines dieser Paare angeben.
„saveExtraState“ und „loadExtraState“
saveExtraState
und loadExtraState
sind Serialisierungs-Hooks, die mit dem
ein neues JSON-Serialisierungssystem. saveExtraState
gibt eine serialisierbare JSON-Datei zurück.
Wert, der den zusätzlichen Status des Blocks darstellt, und loadExtraState
akzeptiert denselben serialisierbaren JSON-Wert und wendet ihn auf den Block an.
// 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_();
},
Die resultierende JSON-Datei sieht so aus:
{
"type": "lists_create_with",
"extraState": {
"itemCount": 3 // or whatever the count is
}
}
Kein Status
Befindet sich Ihr Block bei der Serialisierung im Standardstatus,
Die Methode saveExtraState
kann dazu null
zurückgeben. Wenn Ihr
Die Methode saveExtraState
gibt null
zurück. Dann wird kein extraState
-Attribut hinzugefügt.
das JSON-Format. Dadurch wird die Größe der gespeicherten Datei klein gehalten.
Vollständige Serialisierung und Sicherungsdaten
saveExtraState
empfängt auch einen optionalen doFullSerialization
-Parameter. Dieses
wird von Blöcken verwendet, die auf einen Zustand verweisen, der von einem anderen
Serializer (wie unterstützende Datenmodelle). Der Parameter signalisiert,
Der referenzierte Zustand ist nicht verfügbar, wenn der Block deserialisiert wird, sodass der
Block sollte alle Sicherungsstatus selbst serialisieren. Das ist zum Beispiel
true, wenn ein einzelner Block serialisiert oder wenn ein Block kopiert und eingefügt wird.
Zwei häufige Anwendungsfälle hierfür sind:
- Wenn ein einzelner Block in einen Arbeitsbereich geladen wird, in dem die unterstützenden Daten nicht vorhanden ist, verfügt es über genügend Informationen im eigenen Zustand, um um ein neues Datenmodell zu erstellen.
- Beim Kopieren und Einfügen eines Blocks wird immer eine neue Sicherung erstellt. Datenmodell zu verwenden, anstatt auf ein vorhandenes Modell zu verweisen.
Einige Blöcke, die dies verwenden, sind
@blockly/block-shareable-procedures-Blöcken. Normal
Sie serialisieren einen Verweis auf ein unterstützendes Datenmodell, das ihren Status speichert.
Ist der Parameter doFullSerialization
jedoch "true", werden alle
den jeweiligen Bundesstaat. Die teilbaren Prozedurblöcke nutzen dies, um sicherzustellen,
erstellt ein neues Datenmodell, anstatt auf ein
des vorhandenen Modells.
mutationToDom und domToMutation
mutationToDom
und domToMutation
sind Serialisierungs-Hooks, die mit dem
ein altes XML-Serialisierungssystem. Verwenden Sie diese Aufhänger nur, wenn es unbedingt erforderlich ist (z.B. wenn Sie
auf einer alten Codebasis arbeiten, die noch nicht migriert wurde). Andernfalls verwenden Sie
saveExtraState
und loadExtraState
.
mutationToDom
gibt einen XML-Knoten zurück, der den zusätzlichen Status des
block, und domToMutation
akzeptiert denselben XML-Knoten und wendet den Status auf
des Blocks an.
// 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_();
},
Die resultierende XML-Datei sieht so aus:
<block type="lists_create_with">
<mutation items="3"></mutation>
</block>
Wenn die mutationToDom
-Funktion null zurückgibt, wird kein zusätzliches Element
hinzugefügt.
UI-Hooks
Wenn Sie als Teil Ihres Mutators bestimmte Funktionen bereitstellen, fügt Blockly ein Standard-„Mutator“ UI zu Ihrem Block.
Sie müssen diese UI nicht verwenden, wenn Sie eine zusätzliche Serialisierung hinzufügen möchten. Sie könnten eine benutzerdefinierte UI wie blocks-plus-minus Plug-in oder Sie könnten gar keine Benutzeroberfläche verwenden!
Zusammenfassen und zerlegen
Die Standard-UI stützt sich auf die Funktionen compose
und decompose
.
decompose
„explodiert“ werden in kleinere Unterblöcke unterteilt, die Sie
hinzugefügt und gelöscht haben. Diese Funktion sollte einen "oberen Block" zurückgeben Dieser lautet
Hauptblock im Mutator-Arbeitsbereich, mit dem die Unterblöcke verbunden sind.
compose
interpretiert dann die Konfiguration der Unterblöcke und verwendet sie, um
Hauptblock ändern. Diese Funktion sollte den "oberen Block" akzeptieren. Das war
werden von decompose
als Parameter zurückgegeben.
Beachten Sie, dass diese Funktionen zu „mutierenden“ Block also this
auf diesen Block verweisen.
// 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
Optional können Sie auch eine saveConnections
-Funktion definieren, die mit
die Standardbenutzeroberfläche. Diese Funktion gibt Ihnen die Möglichkeit, untergeordnete Elemente Ihres
Hauptblock (im Hauptarbeitsbereich vorhanden) mit Unterblöcken, die in
Ihrem Mutator-Arbeitsbereich. Anhand dieser Daten können Sie dann dafür sorgen, dass Ihr compose
stellt die Verbindung der untergeordneten Elemente des Hauptblocks her,
werden die Unterblöcke neu angeordnet.
saveConnections
sollte den "oberen" Block akzeptieren von Ihrem Gerät (decompose
) zurückgegeben
als Parameter verwendet werden. Wenn die Funktion saveConnections
definiert ist,
vor compose
aufgerufen wird.
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();
}
},
Wird registriert
Mutatoren sind eine spezielle Erweiterung. Sie müssen also auch registriert, bevor Sie sie im JSON-Format Ihres Blocktyps verwenden können. Definition.
// 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
: Ein String, der mit dem Mutator verknüpft werden soll, damit Sie ihn in JSON verwenden können.mixinObj
: Ein Objekt, das die verschiedenen Mutationsmethoden enthält. Beispiel:saveExtraState
undloadExtraState
.opt_helperFn
: Eine optionale Hilfsfunktion, die nachdem das Mixin vermischt wurde.opt_blockList
: Ein optionales Array von Blocktypen (als Strings), die zum Flyout in der Standard-Mutator-Benutzeroberfläche hinzugefügt, wenn die UI-Methoden ebenfalls definiert.
Im Gegensatz zu Erweiterungen darf jeder Blocktyp nur einen Mutator haben.
{
//...
"mutator": "controls_if_mutator"
}
Hilfsfunktion
Zusammen mit dem Mixin kann ein Mutator eine Hilfsfunktion registrieren. Diese Funktion ist nach seiner Erstellung für jeden Block des angegebenen Typs ausgeführt. hinzugefügt. Damit können einer Mutation zusätzliche Trigger oder Effekte hinzugefügt werden.
Beispielsweise können Sie Ihrem listenähnlichen Block ein Hilfsprogramm hinzufügen, mit dem anfängliche Anzahl von Elementen:
var helper = function() {
this.itemCount_ = 5;
this.updateShape();
}