В июле 2019 года ( выпуск 2.20190722 ) был добавлен более систематизированный API для работы с полями. Он призван обеспечить максимальную обратную совместимость. Это означает, что если вы создали настраиваемое поле до июля 2019 года, оно, скорее всего, продолжит работать. Прежде чем решить, нужно ли обновлять настраиваемое поле, ознакомьтесь с разделом « Опасные зоны» и тщательно протестируйте его.
Из-за отсутствия стандартизации между областями до июля 2019 года сложно охватить все изменения, которые может потребоваться внести разработчику. В этом документе рассматриваются все возможные изменения, но если в нём нет информации о том, что вас интересует, ознакомьтесь с разделом о получении помощи с обновлением .
Опасные зоны
Опасные зоны — это известные места, где API изменился, и ваше поле может быть сломано.
Blockly.Field.register
Поля больше не регистрируются через Blockly.Field.register();
Теперь для регистрации используется пространство имён fieldRegistry
.
Blockly.Field.register('my_field_name', myFieldClass);
Становится:
Blockly.fieldRegistry.register('my_field_name', myFieldClass);
setText
Функция setText
больше не вызывается ядром Blockly, поэтому, если ваша функция setText
содержит логику, ее необходимо переместить в набор функций обработки значений , функцию getText
и функции рендеринга (в зависимости от того, что именно делает ваша функция 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;
};
Становится:
CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
CustomFields.UpgradeField.prototype.getText = function() {
return 'prefix' + this.value_;
}
Blockly автоматически обрабатывает:
- Проверка того, отличается ли новое значение от старого.
- Обновление значения.
- Запуск событий изменения.
- Повторная визуализация поля.
Вам необходимо будет справиться с:
- Проверка значения (
doClassValidation_
). - Текст поля (
getText
). - Полевой пользовательский интерфейс
Рекомендуемые обновления
Рекомендуемые обновления касаются случаев, когда API поля был изменен, но если вы решите не вносить изменения, ваше поле, скорее всего, все равно будет работать.
СЕРИАЛИЗУЕМЫЙ
Дополнительные сведения о свойствах EDITABLE
и SERIALIZABLE
см. в разделе Редактируемые и сериализуемые свойства .
CustomFields.UpgradeField.prototype.SERIALIZABLE = true;
Предупреждение ниже можно игнорировать, но его можно устранить, определив свойство SERIALIZABLE
:
Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.
Предупреждение выше означает, что Blockly считает, что вы хотите сериализовать поле (поскольку свойство EDITABLE
имеет значение true), но не может быть уверен в этом, пока вы не определите свойство SERIALIZABLE
. Если вы оставите это без изменений, всё будет работать корректно, и ваше поле будет сериализовано, но вы получите предупреждения в консоли.
размер_.ширина
this.size_.width = 0;
Становится:
this.isDirty_ = true;
Предупреждение ниже можно игнорировать, но его можно устранить, установив свойство isDirty_
вместо свойства size_.width
:
Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.
Предупреждение выше означает, что Blockly обнаружил, что вы используете старый метод повторной обработки поля, и предлагает вам использовать новый метод.
Дополнительную информацию о свойстве isDirty_
см. в разделе isDirty_ .
инициализация
Функция init
была преобразована в шаблонную функцию для уменьшения дублирования кода в подклассах.
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());
};
Становится:
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_);
};
Это означает, что Blockly теперь автоматически обрабатывает:
- Проверка того, инициализировано ли поле.
- Создание
fieldGroup_
. - Визуализация поля.
- Привязка подсказок и событий редактора показа.
Вам необходимо будет справиться с:
- Добавление дополнительных элементов DOM (
initView
). - Добавление дополнительных привязок событий (
bindEvents_
). - Удаление привязок событий (
dispose
).
onMouseDown_
CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
// ...
};
Становится:
CustomFields.UpgradeField.prototype.showEditor_ = function() {
// ...
}
Мы рекомендуем вам переопределить функцию showEditor_
для обработки щелчков мыши, а не функцию onMouseDown_
, поскольку это позволяет передавать входные данные через систему жестов.
Более подробную информацию о редакторах см. в разделе Редакторы .
setValue
Функция setValue
теперь является шаблонной функцией для уменьшения дублирования кода в подклассах. Если ваша функция setValue
содержит логику, рассмотрите возможность её рефакторинга в соответствии с путями обработки значений, описанными в разделе Обработка значений .
текст_
Мы рекомендуем никогда не обращаться к свойству text_
поля напрямую и не обновлять его. Вместо этого используйте функцию getText
для доступа к тексту поля, доступному для чтения пользователем, и функцию setValue
для обновления сохранённого значения поля.
Дополнительную информацию о значении поля и его тексте см. в разделе Анатомия поля .
Получение помощи по обновлению
Что предоставить
Обращаясь за помощью, лучше всего задавать конкретные вопросы:
Не рекомендуется: «Что не так с этим полем?»
Также не рекомендуется: «Помогите мне обновить это поле».
Рекомендуется: «Текст поля обновляется неправильно».
Также необходимо предоставить ресурсы тем, кто вам помогает. Эти файлы должны быть простыми в использовании.
Не рекомендуется:
- Изображения кода.
- Неполный код.
Рекомендуется:
- Полный код поля в текстовом формате.
- Изображения gif плохого поведения поля.
- Действия по воспроизведению плохого поведения поля.
- Версия Blockly, с которой вы выполняете обновление.
Где разместить
Вопросы по обновлению можно задать на форуме разработчиков Blockly .
Если вы уверены, что проблема связана с ядром Blockly, вы также можете опубликовать сообщение об ошибке на GitHub Blockly. Если вы решите опубликовать сообщение об ошибке, пожалуйста, заполните всю необходимую информацию.