W lipcu 2019 r. (wersja 2.20190722) dodaliśmy bardziej skodyfikowany interfejs API pól. Ma on być w jak największym stopniu zgodny wstecznie. Oznacza to, że jeśli przed lipcem 2019 r. utworzono pole niestandardowe, najprawdopodobniej będzie ono nadal działać. Zanim zdecydujesz, czy Twoje pole niestandardowe wymaga uaktualnienia, przeczytaj sekcję Obszary ryzyka i dokładnie przetestuj pole.
Przed lipcem 2019 r. nie było standardów dotyczących pól, dlatego trudno jest uwzględnić wszystkie zmiany, które deweloper może musieć wprowadzić. Ten dokument zawiera wszystkie prawdopodobne zmiany, ale jeśli nie obejmuje on czegoś, co Cię interesuje, przeczytaj sekcję dotyczącą uzyskiwania pomocy przy uaktualnianiu.
Strefy zagrożenia
Obszary zagrożenia to znane miejsca, w których interfejs API uległ zmianie, a Twoje pole może być uszkodzone.
Blockly.Field.register
Pola nie są już rejestrowane za pomocą Blockly.Field.register();
. Obecnie rejestracją zajmuje się przestrzeń nazw fieldRegistry
.
Blockly.Field.register('my_field_name', myFieldClass);
Zmienia się w:
Blockly.fieldRegistry.register('my_field_name', myFieldClass);
setText
Funkcja setText
nie jest już wywoływana przez rdzeń Blockly, więc jeśli zawiera logikę, musisz ją przenieść do pakietu funkcji obsługi wartości, funkcji getText
i funkcji renderowania (w zależności od tego, co dokładnie robi funkcja setText
).setText
CustomFields.UpgradeField.prototype.setText = function(newText) {
// Do validation.
if (typeof newText != 'string' || newText === this.text_) {
return;
}
// Fire event.
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
Blockly.events.fire(new Blockly.Events.BlockChange(
this.sourceBlock_, 'field', this.name, this.text_, newText
));
}
// Update text value.
this.text_ = 'prefix' + newText;
// Rerender.
this.size_.width = 0;
};
Zmienia się w:
CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
CustomFields.UpgradeField.prototype.getText = function() {
return 'prefix' + this.value_;
}
Blockly automatycznie obsługuje:
- Sprawdzanie, czy nowa wartość różni się od starej.
- Aktualizuję wartość.
- wywoływanie zdarzeń zmiany,
- ponowne renderowanie pola.
Musisz zadbać o:
- Weryfikacja wartości (
doClassValidation_
). - Tekst pola (
getText
). - Interfejs pola
Zalecane aktualizacje
Zalecane uaktualnienia to miejsca, w których interfejs API pola został zmieniony, ale jeśli nie wprowadzisz zmian, pole najprawdopodobniej nadal będzie działać.
SERIALIZABLE
Więcej informacji o właściwościach EDITABLE
i SERIALIZABLE
znajdziesz w artykule Właściwości, które można edytować i serializować.
CustomFields.UpgradeField.prototype.SERIALIZABLE = true;
Poniższe ostrzeżenie można zignorować, ale możesz je rozwiązać, definiując właściwość SERIALIZABLE
:
Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.
Powyższy komunikat ostrzegawczy oznacza, że Blockly uważa, że chcesz serializować pole (ponieważ właściwość EDITABLE
ma wartość true), ale nie może mieć pewności, dopóki nie zdefiniujesz właściwości SERIALIZABLE
. Jeśli nie zmienisz tego ustawienia, wszystko będzie działać prawidłowo, a pole zostanie serializowane, ale w konsoli będą się pojawiać ostrzeżenia.
size_.width
this.size_.width = 0;
Zmienia się w:
this.isDirty_ = true;
Poniższe ostrzeżenie można zignorować, ale możesz je rozwiązać, ustawiając właściwość isDirty_
zamiast właściwości size_.width
:
Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.
Powyższe ostrzeżenie oznacza, że Blockly wykrył, że używasz starej metody ponownego renderowania pola, i zachęca do użycia nowej metody.
Więcej informacji o właściwości isDirty_
znajdziesz w artykule isDirty_.
init
Funkcja init
została przekształcona w funkcję szablonu, aby ograniczyć powielanie kodu w podklasach.
CustomFields.UpgradeField.prototype.init = function() {
if (this.fieldGroup_) {
// Already initialized once.
return;
}
// Call superclass.
CustomFields.UpgradeField.superClass_.init.call(this);
// Create DOM elements.
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
// Bind events.
this.mouseOverWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
// Render.
this.setValue(this.getValue());
};
Zmienia się w:
CustomFields.UpgradeField.prototype.initView = function() {
CustomFields.UpgradeField.superClass_.initView.call(this);
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
};
CustomFields.UpgradeField.prototype.bindEvents_ = function() {
CustomFields.UpgradeField.superClass_.bindEvents_.call(this);
this.mouseOverWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
};
Oznacza to, że Blockly automatycznie obsługuje teraz:
- Sprawdzanie, czy pole zostało już zainicjowane.
- Tworzę
fieldGroup_
. - renderowanie pola,
- Wiązanie etykietki i wyświetlanie zdarzeń edytora.
Musisz zadbać o:
- Dodawanie dodatkowych elementów DOM (
initView
). - Dodawanie kolejnych powiązań zdarzeń (
bindEvents_
). - Usuwanie powiązań zdarzeń (
dispose
).
onMouseDown_
CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
// ...
};
Zmienia się w:
CustomFields.UpgradeField.prototype.showEditor_ = function() {
// ...
}
Zalecamy zastąpienie funkcji showEditor_
funkcją obsługującą kliknięcia myszą zamiast funkcji onMouseDown_
, ponieważ umożliwia to przekazywanie danych wejściowych przez system gestów.
Więcej informacji o edytorach znajdziesz w sekcji Edytorzy.
setValue
Funkcja setValue
jest teraz funkcją szablonu, co pozwala ograniczyć powielanie kodu w podklasach. Jeśli funkcja setValue
zawiera logikę, rozważ jej refaktoryzację, aby pasowała do ścieżek obsługi wartości opisanych w sekcji Obsługa wartości.
text_
Zalecamy, aby nigdy nie uzyskiwać dostępu do właściwości text_
pola ani jej bezpośrednio nie aktualizować. Zamiast tego użyj funkcji getText
setValue
, aby uzyskać dostęp do tekstu pola czytelnego dla użytkownika, oraz funkcji setValue
, aby zaktualizować przechowywaną wartość pola.
Więcej informacji o wartości i tekście pola znajdziesz w artykule Anatomia pola.
Uzyskiwanie pomocy dotyczącej przejścia na wyższą wersję
Co należy podać
Gdy prosisz o pomoc, najlepiej zadawać konkretne pytania:
Niezalecane: „Co jest nie tak z tym polem?”
Nie zalecamy też używania polecenia „Pomóż mi ulepszyć to pole”.
Zalecane: „Tekst pola nie jest prawidłowo aktualizowany”.
Konieczne jest również udostępnienie zasobów osobom, które Ci pomagają. Te pliki powinny być łatwe w użyciu dla innych osób.
Niezalecane:
- zdjęcia kodu;
- Niepełny kod.
Zalecane:
- Uzupełnij kod pola w formacie tekstowym.
- Obrazy GIF przedstawiające nieprawidłowe działanie w polu.
- Kroki umożliwiające odtworzenie nieprawidłowego działania pola.
- Wersja Blockly, z której uaktualniasz.
Gdzie opublikować
Pytania dotyczące uaktualnienia możesz zadawać na forum dla deweloperów Blockly.
Jeśli masz pewność, że problem dotyczy podstawowej wersji Blockly, możesz też zgłosić problem na GitHubie Blockly. Jeśli zdecydujesz się opublikować problem, podaj wszystkie wymagane informacje.