Zanim utworzysz nowy typ pola, zastanów się, czy któraś z innych metod dostosowywania pól nie odpowiada Twoim potrzebom. Jeśli aplikacja musi przechowywać nowy typ wartości lub jeśli chcesz utworzyć nowy interfejs dla istniejącego typu wartości, prawdopodobnie musisz utworzyć nowy typ pola.
Aby utworzyć nowe pole:
- Zaimplementuj konstruktor.
- Zarejestruj klucz JSON i zaimplementuj
fromJson
. - Obsługa inicjowania interfejsu użytkownika bloku i odbiorników zdarzeń
- Usuwaj detektory zdarzeń (usuwanie w interfejsie odbywa się za Ciebie).
- Wdróż obsługę wartości.
- Dodaj tekstowe przedstawienie wartości pola na potrzeby ułatwień dostępu.
- Możesz korzystać z dodatkowych funkcji, takich jak:
- Skonfiguruj dodatkowe aspekty pola, takie jak:
W tej sekcji zakładamy, że znasz już treść artykułu Anatomia pola.
Przykład pola niestandardowego znajdziesz w prezentacji o polach niestandardowych.
Implementowanie konstruktora
Konstruktor pola odpowiada za ustawienie początkowej wartości pola oraz opcjonalnie skonfigurowanie lokalnego walidatora. Konstruktor pola niestandardowego jest wywoływany podczas inicjowania bloku źródłowego niezależnie od tego, czy blok źródłowy jest zdefiniowany w formacie JSON czy JavaScript. Pole niestandardowe nie ma więc dostępu do bloku źródłowego podczas tworzenia.
Ten przykładowy kod tworzy pole niestandardowe o nazwie GenericField
:
class GenericField extends Blockly.Field {
constructor(value, validator) {
super(value, validator);
this.SERIALIZABLE = true;
}
}
Podpis metody
Konstruktory pól zwykle przyjmują wartość i lokalny walidator. Wartość jest opcjonalna. Jeśli nie przekażesz wartości (lub wartości, która nie przejdzie weryfikacji klasy), zostanie użyta wartość domyślna klasy nadrzędnej. W przypadku domyślnej klasy Field
ta wartość wynosi null
. Jeśli nie chcesz używać tej wartości domyślnej, prześlij odpowiednią wartość. Parametr walidatora występuje tylko w polach do edycji i jest zwykle oznaczony jako opcjonalny. Więcej informacji o walidatorach znajdziesz w dokumentacji walidatorów.
Struktura
Logika konstruktora powinna wyglądać tak:
- Wywołaj dziedziczony superkonstruktor (wszystkie pola niestandardowe powinny dziedziczyć z klasy
Blockly.Field
lub jednej z jej podklas), aby prawidłowo zainicjować wartość i ustawić lokalny walidator pola. - Jeśli pole można zserializować, ustaw odpowiednią właściwość w konstruktorze. Pola, które można edytować, muszą być serializowane, a pola domyślnie można edytować, więc prawdopodobnie ustaw tę właściwość na „true” (prawda), chyba że wiesz, że nie powinna być ona szeregowa.
- Opcjonalnie: zastosuj dodatkowe dostosowanie (np. pola etykiet umożliwiają przekazywanie klasy CSS, która jest następnie stosowana do tekstu).
JSON i rejestracja
W definicjach bloków JSON pola są opisywane ciągiem znaków (np. field_number
, field_textinput
). Blockly zachowuje mapowanie tych ciągów znaków na obiekty pól i wywołuje fromJson
do odpowiedniego obiektu podczas tworzenia.
Wywołaj Blockly.fieldRegistry.register
, aby dodać typ pola do tej mapy, przekazując klasę pola jako drugi argument:
Blockly.fieldRegistry.register('field_generic', GenericField);
Musisz też zdefiniować funkcję fromJson
. W implementacji należy najpierw usunąć odniesienia do wszystkich odwołań do tabeli ciągów za pomocą funkcji replaceMessageReferences, a potem przekazać wartości do konstruktora.
GenericField.fromJson = function(options) {
const value = Blockly.utils.parsing.replaceMessageReferences(
options['value']);
return new CustomFields.GenericField(value);
};
Inicjuję
W ramach tworzenia pola znajduje się w nim tylko wartość. Inicjacja to miejsce, w którym tworzony jest DOM, model jest tworzony (jeśli pole zawiera model), a zdarzenia są powiązane.
Ekran typu Blokuj ekran
Podczas inicjowania odpowiadasz za utworzenie wszystkiego, co jest potrzebne do wyświetlania pola.
Domyślne ustawienia, tło i tekst
Domyślna funkcja initView
tworzy element rect
w jasnym kolorze i element text
. Jeśli chcesz, aby pole miało oba te elementy oraz dodatkowe korzyści, wywołaj funkcję initView
superklasy przed dodaniem pozostałych elementów DOM. Jeśli chcesz, aby pole miało jeden z tych elementów, ale nie oba, możesz użyć funkcji createBorderRect_
lub createTextElement_
.
Dostosowywanie konstrukcji DOM
Jeśli pole jest standardowym polem tekstowym (np. Dane wejściowe), konstrukcja DOM zostanie wykonana za Ciebie. W przeciwnym razie musisz zastąpić funkcję initView
, aby utworzyć elementy DOM, których będziesz potrzebować podczas przyszłego renderowania pola.
Na przykład pole rozwijane może zawierać zarówno obrazy, jak i tekst. W initView
tworzy 1 element graficzny i 1 element tekstowy. Następnie w okresie render_
wyświetla aktywny element i ukrywa drugi na podstawie typu wybranej opcji.
Elementy DOM można tworzyć za pomocą metody Blockly.utils.dom.createSvgElement
lub tradycyjnych metod tworzenia DOM.
Wymagania dotyczące wyświetlania pola w bloku to:
- Wszystkie elementy DOM muszą być elementami podrzędnymi
fieldGroup_
pola. Grupa pól zostanie utworzona automatycznie. - Wszystkie elementy DOM muszą mieścić się w raportowanych wymiarach pola.
Więcej informacji o dostosowywaniu i aktualizowaniu wyświetlacza na ekranie znajdziesz w sekcji Renderowanie.
Dodawanie symboli tekstowych
Jeśli chcesz dodać symbole do tekstu pola (np. symbol stopni w polu Kąt), możesz dołączyć element symbolu (zwykle zawarty w <tspan>
) bezpośrednio do parametru textElement_
tego pola.
Zdarzenia wejściowe
Domyślnie pola rejestrują zdarzenia etykietki i zdarzenia kursora myszy (które służą do wyświetlania edytorów).
Jeśli chcesz wykrywać zdarzenia innego typu (np. obsługiwać przeciąganie w polu), zastąp funkcję bindEvents_
tego pola.
bindEvents_() {
// Call the superclass function to preserve the default behavior as well.
super.bindEvents_();
// Then register your own additional event listeners.
this.mouseDownWrapper_ =
Blockly.browserEvents.conditionalBind(this.getClickTarget_(), 'mousedown', this,
function(event) {
this.originalMouseX_ = event.clientX;
this.isMouseDown_ = true;
this.originalValue_ = this.getValue();
event.stopPropagation();
}
);
this.mouseMoveWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mousemove', this,
function(event) {
if (!this.isMouseDown_) {
return;
}
var delta = event.clientX - this.originalMouseX_;
this.setValue(this.originalValue_ + delta);
}
);
this.mouseUpWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mouseup', this,
function(_event) {
this.isMouseDown_ = false;
}
);
}
Aby powiązać ze zdarzeniem, użyj funkcji Blockly.utils.browserEvents.conditionalBind
. Ta metoda wiązania zdarzeń odfiltrowuje dodatkowe kliknięcia podczas przeciągania. Jeśli chcesz, aby moduł obsługi był uruchamiany nawet w trakcie przeciągania, możesz użyć funkcji Blockly.browserEvents.bind
.
Utylizacja
Jeśli masz zarejestrowane detektory zdarzeń niestandardowych w funkcji bindEvents_
tego pola, musisz je wyrejestrować w ramach funkcji dispose
.
Jeśli prawidłowo zainicjujesz widok pola (przez dołączenie wszystkich elementów DOM do fieldGroup_
), to DOM dla tego pola zostanie usunięty automatycznie.
Obsługa wartości
→ Informacje o wartości pola i jego tekście znajdziesz w artykule Anatomia pola.
Kolejność weryfikacji
Wdrażanie walidatora klas
Pola powinny przyjmować tylko określone wartości. Na przykład pola liczbowe powinny akceptować tylko liczby, pola kolorów – tylko kolory itp. Jest to możliwe dzięki klasom i lokalnym walidatorom. Walidator klas działa tak samo jak lokalne walidatory, z tym że jest uruchamiany w konstruktorze i dlatego nie powinien odwoływać się do bloku źródłowego.
Aby wdrożyć walidator klas pola, zastąp funkcję doClassValidation_
.
doClassValidation_(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
Obsługa prawidłowych wartości
Jeśli wartość przekazana do pola z setValue
jest prawidłowa, otrzymasz wywołanie zwrotne doValueUpdate_
. Domyślnie funkcja doValueUpdate_
:
- Ustawia właściwość
value_
nanewValue
. - Ustawia wartość właściwości
isDirty_
natrue
.
Jeśli chcesz po prostu zapisać wartość i nie chcesz stosować żadnej niestandardowej obsługi, nie musisz zastępować atrybutu doValueUpdate_
.
W przeciwnym razie możesz:
- Pamięć niestandardowa
newValue
. - Zmień inne usługi na podstawie:
newValue
. - Zapisz, czy bieżąca wartość jest prawidłowa.
Musisz zastąpić zasadę doValueUpdate_
:
doValueUpdate_(newValue) {
super.doValueUpdate_(newValue);
this.displayValue_ = newValue;
this.isValueValid_ = true;
}
Obsługa nieprawidłowych wartości
Jeśli wartość przekazana do pola z setValue
jest nieprawidłowa, otrzymasz wywołanie zwrotne doValueInvalid_
. Domyślnie funkcja doValueInvalid_
nic nie robi. Oznacza to, że domyślnie nieprawidłowe wartości nie będą wyświetlane. Oznacza to również, że pole nie zostanie ponownie wyrenderowane, ponieważ właściwość isDirty_
nie zostanie ustawiona.
Jeśli chcesz wyświetlić nieprawidłowe wartości, zastąp doValueInvalid_
.
W większości przypadków należy ustawić wartość właściwości displayValue_
na nieprawidłową wartość, ustawić isDirty_
na true
i zastąpić renderowanie_ w przypadku wyświetlenia blokowego, aby aktualizowało się na podstawie displayValue_
, a nie value_
.
doValueInvalid_(newValue) {
this.displayValue_ = newValue;
this.isDirty_ = true;
this.isValueValid_ = false;
}
Wartości wieloczęściowe
Jeśli pole zawiera wartość wieloczęściową (np. listy, wektory, obiekty), możesz chcieć, aby części były traktowane jak pojedyncze wartości.
doClassValidation_(newValue) {
if (FieldTurtle.PATTERNS.indexOf(newValue.pattern) == -1) {
newValue.pattern = null;
}
if (FieldTurtle.HATS.indexOf(newValue.hat) == -1) {
newValue.hat = null;
}
if (FieldTurtle.NAMES.indexOf(newValue.turtleName) == -1) {
newValue.turtleName = null;
}
if (!newValue.pattern || !newValue.hat || !newValue.turtleName) {
this.cachedValidatedValue_ = newValue;
return null;
}
return newValue;
}
W powyższym przykładzie każda właściwość obiektu newValue
jest sprawdzana indywidualnie. Jeśli któraś właściwość jest nieprawidłowa, na końcu funkcji doClassValidation_
wartość jest przechowywana w pamięci podręcznej właściwości cacheValidatedValue_
, a następnie zwracana wartość null
(nieprawidłowa). Zapisywanie obiektów w pamięci podręcznej z pojedynczymi właściwościami pozwala funkcji doValueInvalid_
obsługiwać je oddzielnie, przeprowadzając sprawdzanie !this.cacheValidatedValue_.property
zamiast ponownie weryfikować każdą właściwość z osobna.
Z tego wzorca do weryfikacji wartości wieloczęściowych można też korzystać w lokalnych walidatorach, ale obecnie nie da się go wymusić.
isDirty_
isDirty_
to flaga używana w funkcji setValue
oraz w innych częściach pola, aby określić, czy pole należy wyrenderować ponownie. Jeśli wyświetlana wartość pola uległa zmianie, isDirty_
zazwyczaj należy ustawić na true
.
Tekst
→ Informacje o tym, gdzie jest używany tekst pola i czym różni się on od jego wartości, znajdziesz w artykule Anatomia pola.
Jeśli treść pola różni się od wartości pola, zastąp funkcję getText
, aby wpisać prawidłowy tekst.
getText() {
let text = this.value_.turtleName + ' wearing a ' + this.value_.hat;
if (this.value_.hat == 'Stovepipe' || this.value_.hat == 'Propeller') {
text += ' hat';
}
return text;
}
Tworzenie edytora
Jeśli zdefiniujesz funkcję showEditor_
, Blockly będzie automatycznie nasłuchiwać kliknięć i wywołać funkcję showEditor_
w odpowiednim momencie. Możesz wyświetlić dowolny kod HTML w edytorze, zawijając go do jednego z dwóch specjalnych elementów div o nazwie DropDownDiv i WidgetDiv, które unoszą się nad pozostałymi elementami interfejsu Blockly.
DropDownDiv a WidgetDiv
DropDownDiv
umożliwia edytorom, którzy znajdują się w obiekcie połączonym z polem. Automatycznie ustawia się w pobliżu pola, a jednocześnie mieści się w widocznym obszarze. Dobrymi przykładami właściwości DropDownDiv
są selektor kąta i selektor kolorów.
WidgetDiv
służy do udostępniania edytorów, które nie znajdują się w polu. Pola liczbowe korzystają z WidgetDiv do zasłaniania pola polem do wprowadzania tekstu HTML. Pozycjonowanie za pomocą uchwytów DropDownDiv jest natomiast możliwe w przypadku narzędzia WidgetDiv. Elementy należy ustawić ręcznie. Układ współrzędnych podany jest we współrzędnych piksela względem lewego górnego rogu okna. Dobrym przykładem funkcji WidgetDiv
jest edytor do wprowadzania tekstu.
Przykładowy kod DropDownDiv
showEditor_() {
// Create the widget HTML
this.editor_ = this.dropdownCreate_();
Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_);
// Set the dropdown's background colour.
// This can be used to make it match the colour of the field.
Blockly.DropDownDiv.setColour('white', 'silver');
// Show it next to the field. Always pass a dispose function.
Blockly.DropDownDiv.showPositionedByField(
this, this.disposeWidget_.bind(this));
}
Przykładowy kod WidgetDiv
showEditor_() {
// Show the div. This automatically closes the dropdown if it is open.
// Always pass a dispose function.
Blockly.WidgetDiv.show(
this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
// Create the widget HTML.
var widget = this.createWidget_();
Blockly.WidgetDiv.getDiv().appendChild(widget);
}
Czyszczenie
Zarówno uchwyt DropDownDiv, jak i uchwyt WidgetDiv niszczą elementy HTML widżetu, ale musisz ręcznie pozbyć się detektorów zdarzeń zastosowanych do tych elementów.
widgetDispose_() {
for (let i = this.editorListeners_.length, listener;
listener = this.editorListeners_[i]; i--) {
Blockly.browserEvents.unbind(listener);
this.editorListeners_.pop();
}
}
Funkcja dispose
jest wywoływana w kontekście null
w elemencie DropDownDiv
. Na urządzeniu WidgetDiv
jest ono wywoływane w kontekście obiektu WidgetDiv
. W obu przypadkach najlepiej jest użyć funkcji bind podczas przekazywania funkcji dispose, jak pokazano w powyższych przykładach DropDownDiv
i WidgetDiv
.
→ Informacje na temat utylizacji, które nie są związane z utylizowaniem redaktorów, znajdziesz w artykule Nikonikowanie.
Aktualizacja wyświetlacza blokowego
Funkcja render_
służy do aktualizowania wyświetlacza w bloku pola, tak aby pasował do jego wewnętrznej wartości.
Typowe przykłady:
- Zmiana tekstu (menu)
- Zmiana koloru
Domyślne
Domyślna funkcja render_
ustawia wyświetlany tekst na wynik funkcji getDisplayText_
. Funkcja getDisplayText_
zwraca właściwość value_
pola rzutowaną na ciąg znaków po skróceniu z uwzględnieniem maksymalnej długości tekstu.
Jeśli używasz domyślnego wyświetlania blokad, a domyślne zachowanie tekstu w Twoim polu działa, nie musisz zastępować parametru render_
.
Jeśli w przypadku Twojego pola działa domyślny tekst, ale w przypadku tego pola dostępne są dodatkowe elementy statyczne, możesz wywołać domyślną funkcję render_
, ale i tak musisz ją zastąpić, by zmienić rozmiar pola.
Jeśli domyślne zachowanie tekstu nie działa w przypadku Twojego pola lub wyświetlane w nim elementy wyświetlane w bloku mają dodatkowe elementy dynamiczne, musisz dostosować funkcję render_
.
Dostosowywanie renderowania
Jeśli domyślne zachowanie renderowania nie działa w Twoim polu, musisz zdefiniować niestandardowe zachowanie renderowania. Może to obejmować wszystko: od ustawienia niestandardowego tekstu przez zmianę elementów obrazu po zmianę kolorów tła.
Wszystkie zmiany atrybutów DOM są zgodne z prawem. Należy pamiętać tylko o 2 kwestiach:
- Tworzenie DOM powinno być przeprowadzane podczas inicjowania, ponieważ jest to bardziej efektywne.
- Zawsze musisz zaktualizować właściwość
size_
, aby pasowała do rozmiaru wyświetlacza blokowego.
render_() {
switch(this.value_.hat) {
case 'Stovepipe':
this.stovepipe_.style.display = '';
break;
case 'Crown':
this.crown_.style.display = '';
break;
case 'Mask':
this.mask_.style.display = '';
break;
case 'Propeller':
this.propeller_.style.display = '';
break;
case 'Fedora':
this.fedora_.style.display = '';
break;
}
switch(this.value_.pattern) {
case 'Dots':
this.shellPattern_.setAttribute('fill', 'url(#polkadots)');
break;
case 'Stripes':
this.shellPattern_.setAttribute('fill', 'url(#stripes)');
break;
case 'Hexagons':
this.shellPattern_.setAttribute('fill', 'url(#hexagons)');
break;
}
this.textContent_.nodeValue = this.value_.turtleName;
this.updateSize_();
}
Aktualizuję rozmiar
Aktualizacja właściwości size_
pola jest bardzo ważna, ponieważ informuje kod renderowania blokowego o położeniu pola. Aby dowiedzieć się, co dokładnie powinna mieć wartość size_
, najlepiej jest poeksperymentować.
updateSize_() {
const bbox = this.movableGroup_.getBBox();
let width = bbox.width;
let height = bbox.height;
if (this.borderRect_) {
width += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
height += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
this.borderRect_.setAttribute('width', width);
this.borderRect_.setAttribute('height', height);
}
// Note how both the width and the height can be dynamic.
this.size_.width = width;
this.size_.height = height;
}
Dopasowane kolory bloków
Jeśli chcesz, aby elementy pola były zgodne z kolorami bloku, do którego są dołączone, zastąp metodę applyColour
. Dostęp do koloru należy uzyskać
za pomocą właściwości stylu bloku.
applyColour() {
const sourceBlock = this.sourceBlock_;
if (sourceBlock.isShadow()) {
this.arrow_.style.fill = sourceBlock.style.colourSecondary;
} else {
this.arrow_.style.fill = sourceBlock.style.colourPrimary;
}
}
Aktualizuję możliwość edytowania
Za pomocą funkcji updateEditable
możesz zmieniać wygląd pola w zależności od tego, czy można je edytować. Funkcja domyślna sprawia, że w tle pojawia się odpowiedź po najechaniu kursorem (obramowanie) – jeśli jej nie można edytować.
Rozmiar wyświetlany podczas blokowania nie powinien zmieniać rozmiaru w zależności od możliwości edytowania, ale wszelkie inne zmiany są dozwolone.
updateEditable() {
if (!this.fieldGroup_) {
// Not initialized yet.
return;
}
super.updateEditable();
const group = this.getClickTarget_();
if (!this.isCurrentlyEditable()) {
group.style.cursor = 'not-allowed';
} else {
group.style.cursor = this.CURSOR;
}
}
Serializacja
Serializacja polega na zapisywaniu stanu pola, aby można było później ponownie załadować je do obszaru roboczego.
Stan obszaru roboczego zawsze zawiera wartość pola, ale może też zawierać inny stan, na przykład stan interfejsu pola. Jeśli na przykład pole to mapa z możliwością powiększania i umożliwiająca użytkownikowi wybranie krajów, możesz też serializować poziom powiększenia.
Jeśli Twoje pole można serializować, ustaw właściwość SERIALIZABLE
na true
.
Blockly udostępnia 2 zestawy punktów zaczepienia serializacji dla pól. Jedna para zaczepów działa z nowym systemem serializacji JSON, a druga ze starym systemem serializacji XML.
saveState
i loadState
saveState
i loadState
to punkty zaczepienia serializacji, które działają z nowym systemem serializacji JSON.
W niektórych przypadkach nie trzeba ich podawać, ponieważ będą działać domyślne implementacje. Jeśli (1) Twoje pole jest bezpośrednią podklasą klasy podstawowej Blockly.Field
, (2) wartość jest typem zserializowanym w JSON oraz (3) musisz tylko przeprowadzić serializację wartości, wtedy domyślna implementacja będzie działać prawidłowo.
W przeciwnym razie funkcja saveState
powinna zwracać możliwe do zserializowania obiekt/wartość JSON, która reprezentuje stan pola. A funkcja loadState
powinna akceptować ten sam obiekt/wartość JSON z możliwością serializowania i zastosować go do pola.
saveState() {
return {
'country': this.getValue(), // Value state
'zoom': this.getZoomLevel(), // UI state
};
}
loadState(state) {
this.setValue(state['country']);
this.setZoomLevel(state['zoom']);
}
Pełna serializacja i tworzenie kopii zapasowych danych
saveState
otrzymuje też opcjonalny parametr doFullSerialization
. Jest ona używana w przypadku pól, które zwykle odwołują się do stanu zserializowanego przez inny serializer (np. zapasowe modele danych). Parametr sygnalizuje, że dany stan nie będzie dostępny, gdy blok zostanie poddany deserializacji, dlatego pole powinno wykonywać całą serializację. Dzieje się tak np. wtedy, gdy pojedynczy blok jest zserializowany lub gdy blok jest kopiowany i wklejany.
Oto 2 typowe przypadki użycia tej funkcji:
- Po wczytaniu pojedynczego bloku do obszaru roboczego, w którym nie istnieje bazowy model danych, pole ma wystarczającą ilość informacji w swoim stanie, aby utworzyć nowy model danych.
- Gdy blok jest skopiowany i wklejony, pole zawsze tworzy nowy zapasowy model danych, zamiast odwoływać się do istniejącego.
Jedno z nich to pole wbudowanej zmiennej. Zwykle zserializuje identyfikator zmiennej, do której się odwołuje, ale jeśli doFullSerialization
ma wartość prawda, zserializuje cały swój stan.
saveState(doFullSerialization) {
const state = {'id': this.variable_.getId()};
if (doFullSerialization) {
state['name'] = this.variable_.name;
state['type'] = this.variable_.type;
}
return state;
}
loadState(state) {
const variable = Blockly.Variables.getOrCreateVariablePackage(
this.getSourceBlock().workspace,
state['id'],
state['name'], // May not exist.
state['type']); // May not exist.
this.setValue(variable.getId());
}
Pole zmiennej ma służyć do zapewnienia, że jeśli zostanie wczytane w obszarze roboczym, w którym nie ma odpowiedniej zmiennej, może utworzyć nową zmienną, do której się ona odwoła.
toXml
i fromXml
toXml
i fromXml
to punkty zaczepienia serializacji, które działają ze starym systemem serializacji XML. Używaj tych punktów zaczepienia tylko wtedy, gdy to konieczne (np.pracujesz nad starą bazą kodu, która nie została jeszcze przeniesiona). W innych przypadkach używaj saveState
i loadState
.
Funkcja toXml
powinna zwracać węzeł XML, który reprezentuje stan pola. Funkcja fromXml
powinna akceptować ten sam węzeł XML i stosować go do pola.
toXml(fieldElement) {
fieldElement.textContent = this.getValue();
fieldElement.setAttribute('zoom', this.getZoomLevel());
return fieldElement;
}
fromXml(fieldElement) {
this.setValue(fieldElement.textContent);
this.setZoomLevel(fieldElement.getAttribute('zoom'));
}
Właściwości możliwe do edycji i serializacji
Właściwość EDITABLE
określa, czy pole powinno mieć interfejs wskazujący, z którym można wchodzić w interakcje. Domyślna wartość to true
.
Właściwość SERIALIZABLE
określa, czy pole powinno być zserializowane. Domyślna wartość to false
. Jeśli ta właściwość to true
, może być konieczne udostępnienie funkcji serializacji i deserializacji (patrz Serializacja).
Dostosowywanie kursora
Właściwość CURSOR
określa kursor, który użytkownicy widzą po najechaniu kursorem na pole. Powinien to być prawidłowy ciąg kursora CSS. Domyślnie jest to kursor zdefiniowany przez atrybut .blocklyDraggable
, który jest chwytanym kursorem.