Rozszerzenia to funkcje, które działają w każdym bloku danego typu, gdy blok jest Utworzono. Często powodują one dodanie do bloku niestandardowej konfiguracji lub zachowania.
Mutator to szczególnego rodzaju rozszerzenie, które dodaje niestandardową serializację. lub innym.
Rozszerzenia
Rozszerzenia to funkcje, które działają w każdym bloku danego typu, gdy blok jest Utworzono. Może dodać konfigurację niestandardową (np. ustawić etykietkę bloku) lub zachowanie niestandardowe (np. dodanie do bloku detektora zdarzeń).
// 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;
});
});
Rozszerzenia muszą być „zarejestrowane” aby można je było powiązać z ciągiem
. Następnie możesz przypisać ten klucz ciągu do właściwości extensions
na Twojej
JSON dla typu bloku
definicji, aby zastosować
z blokiem.
{
//...,
"extensions": ["parent_tooltip_extension",]
}
Możesz też dodać wiele rozszerzeń jednocześnie. Pamiętaj, że w polu extensions
musi być tablicą, nawet jeśli stosujesz tylko jedno rozszerzenie.
{
//...,
"extensions": ["parent_tooltip_extension", "break_warning_extension"],
}
Składanki
Blockly to także wygodna metoda w sytuacjach, w których chcesz dodawać właściwości/funkcje pomocnicze w danym bloku, ale nie uruchamiają ich od razu. Ten działa, umożliwiając zarejestrowanie składniki , który zawiera wszystkie dodatkowe właściwości/metody. Obiekt wymieszania jest następnie opakowana w funkcji, która stosuje mieszankę za każdym razem, gdy wystąpienie podany typ blokady.
Blockly.Extensions.registerMixin('my_mixin', {
someProperty: 'a cool value',
someMethod: function() {
// Do something cool!
}
))`
Do kluczy łańcuchowych powiązanych z kombinacjami można się odwoływać w formacie JSON tak jak do każdego innego .
{
//...,
"extensions": ["my_mixin"],
}
Mutatory
Mutator to specjalny typ rozszerzenia, który dodaje serializację (dodatkowe
który jest zapisywany i wczytywany) do bloku. Dotyczy to na przykład wbudowanego
Bloki controls_if
i list_create_with
wymagają dodatkowej serializacji,
mogą zapisać liczbę
podanych danych wejściowych.
Pamiętaj, że zmiana kształtu bryły nie musi oznaczać konieczności
to dodatkowa serializacja. Na przykład blok math_number_property
zmienia się
kształtu, ale robi to na podstawie pola rozwijanego, którego wartość jest
zserializowany. W ten sposób można użyć po prostu pola,
walidatorowi i nie
potrzebujesz mutatora.
Zapoznaj się z artykułem o serializacji strony w przypadku o tym, kiedy potrzebujesz mutatora, a kiedy nie.
Mutatory mają też wbudowany interfejs użytkownika, za pomocą którego użytkownik może zmieniać kształt brył, możesz udostępnić kilka metod opcjonalnych.
Punkty zaczepienia serializacji
Mutatory mają dwie pary punktów zaczepienia serializacji, z którymi współpracują. 1 para haczyków działa z nowym systemem serializacji JSON, a druga para działa z starego systemu serializacji XML. Musisz podać co najmniej jedną z tych par.
SaveExtraState i loadExtraState
saveExtraState
i loadExtraState
to punkty zaczepienia serializacji, które współpracują z parametrami
nowego systemu serializacji JSON. saveExtraState
zwraca serializowalny kod JSON
wartość, która reprezentuje dodatkowy stan bloku, oraz loadExtraState
akceptuje tę samą serializowalną wartość JSON i stosuje ją do bloku.
// 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_();
},
Wynikowy kod JSON będzie wyglądał tak:
{
"type": "lists_create_with",
"extraState": {
"itemCount": 3 // or whatever the count is
}
}
Brak stanu
Jeśli podczas serializacji blok jest w stanie domyślnym,
Metoda saveExtraState
może zwracać wartość null
, aby to zaznaczyć. Jeśli
Metoda saveExtraState
zwraca wartość null
, następnie do argumentu nie dodano żadnej właściwości extraState
w formacie JSON. Dzięki temu rozmiar zapisywanego pliku będzie niewielki.
Pełna serializacja i dane kopii zapasowej
Funkcja saveExtraState
otrzymuje też opcjonalny parametr doFullSerialization
. Ten
jest używany przez bloki, które odwołują się do stanu zserializowanego przez inny
serializer (np. zapasowe modele danych). Parametr ten informuje,
wskazany stan nie będzie dostępny, gdy blok zostanie deserializowany, więc
powinien zserializować cały stan kopii zapasowej. Na przykład jest to
true (prawda), gdy pojedynczy blok jest zserializowany lub gdy blok jest skopiowany i wklejony.
Są to 2 częste przypadki użycia:
- Gdy pojedynczy blok jest wczytywany do obszaru roboczego, w którym dane zapasowe model nie istnieje, ale ma w swoim stanie wystarczająco dużo informacji, w celu utworzenia nowego modelu danych.
- Kopiowanie i wklejanie bloku zawsze powoduje utworzenie nowej kopii zapasowej model danych zamiast odwoływania się do istniejącego.
Niektóre bloki, które z niego korzystają, to
blokady @blockly/block-shareable-procedures. Normalnie
zserializują odwołanie do bazowego modelu danych, w którym znajduje się ich stan.
Jeśli jednak parametr doFullSerialization
ma wartość prawda, zserializowane są wszystkie wartości
ze swojego stanu. Korzystają z niej blokady procedury udostępniania, aby mieć pewność, że
są kopiowane i wklejane, co pozwala utworzyć nowy bazowy model danych, zamiast odwoływać się
istniejącego modelu.
mutationToDom i domToMutation
mutationToDom
i domToMutation
to punkty zaczepienia serializacji, które współpracują z parametrami
starego systemu serializacji XML. Używaj tych haczyków tylko wtedy, gdy jest to konieczne (np.
na starej bazie kodu, która nie została jeszcze przeniesiona), w przeciwnym razie użyj
saveExtraState
i loadExtraState
.
mutationToDom
zwraca węzeł XML, który reprezentuje dodatkowy stan funkcji
blok, a domToMutation
akceptuje ten sam węzeł XML i stosuje stan do
do blokowania bloków.
// 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_();
},
Powstały kod XML będzie wyglądał tak:
<block type="lists_create_with">
<mutation items="3"></mutation>
</block>
Jeśli funkcja mutationToDom
zwraca wartość null, żaden dodatkowy element nie będzie
dodany do pliku XML.
Elementy przykuwające UI
Jeśli podasz określone funkcje jako część mutatora, Blockly doda tag domyślny „mutator” Interfejs użytkownika do bloku.
Nie musisz używać tego interfejsu, jeśli chcesz dodać dodatkową serializację. Możesz użyć niestandardowego interfejsu, takiego jak blocks-plus-minus wtyczka lub nie chcesz w ogóle korzystać z interfejsu.
tworzenie i rozkładanie
Domyślny interfejs użytkownika korzysta z funkcji compose
i decompose
.
decompose
– wybuch na mniejsze bloki podrzędne, które można przesuwać
oraz dodawać i usuwać. Ta funkcja powinna zwrócić „górny blok” czyli
blok główny w obszarze roboczym mutatora, z którym łączą się bloki podrzędne.
compose
następnie interpretuje konfigurację podbloków i używa ich do
i zmodyfikować blok główny. Ta funkcja powinna akceptować „górny blok” co było
zwracanych przez funkcję decompose
jako parametr.
Zwróć uwagę, że te funkcje są „mieszane” do „mutowanego” bloku więc this
można powołać się na tę blokadę.
// 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
Opcjonalnie możesz również zdefiniować funkcję saveConnections
, która działa z
do domyślnego interfejsu. Ta funkcja umożliwia powiązanie elementów podrzędnych
blok główny (istniejący w głównym obszarze roboczym) z blokami podrzędnymi występującymi w
obszaru roboczego mutatora. Możesz potem użyć tych danych, aby sprawdzić, czy Twoje urządzenie compose
prawidłowo ponownie łączy elementy podrzędne bloku głównego, gdy
a bloki podrzędne zostają uporządkowane.
saveConnections
powinien zaakceptować „górny blok” zwrócone przez: decompose
jako parametru. Jeśli zdefiniowano funkcję saveConnections
, Blockly
Zadzwoni przed zadzwonieniem pod numer 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();
}
},
Rejestruję…
Mutatory to specjalny rodzaj rozszerzeń, więc muszą , zanim będzie można ich używać w JSON typu bloku .
// 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
: ciąg znaków do powiązania z mutatorem, aby można było go użyć w formacie JSON.mixinObj
: obiekt zawierający różne metody mutacji. Na przykład:saveExtraState
iloadExtraState
.opt_helperFn
: opcjonalna funkcja pomocnicza, która będzie po wymieszaniu mieszanin.opt_blockList
: opcjonalna tablica typów bloków (w formie ciągów znaków), która zostanie jest dodawana do menu rozwijanego w domyślnym interfejsie mutatora, jeśli metody interfejsu zdefiniowano jego definicję.
Pamiętaj, że w przeciwieństwie do rozszerzeń każdy typ bloku może mieć tylko jeden mutator.
{
//...
"mutator": "controls_if_mutator"
}
Funkcja pomocnicza
Wraz z mikserem mutator może zarejestrować funkcję pomocniczą. Ta funkcja jest po utworzeniu każdego bloku danego typu, a miksinObj ma – dodano. Można jej użyć do dodania do mutacji dodatkowych wyzwalaczy lub efektów.
Możesz na przykład dodać do bloku listy funkcji pomocniczej, która ustawia początkowa liczba elementów:
var helper = function() {
this.itemCount_ = 5;
this.updateShape();
}