Обновить настраиваемое поле

В июле 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 автоматически обрабатывает:

  • Проверка, отличается ли новое значение от старого.
  • Обновление значения.
  • События, связанные со сменой режима стрельбы.
  • Перерисовка поля.

Вам потребуется выполнить следующие действия:

Рекомендуемые обновления — это те места, где были внесены изменения в API поля, но если вы решите не вносить изменения, ваше поле, скорее всего, продолжит работать.

СЕРИЙНЫЙ

Для получения дополнительной информации о свойствах EDITABLE и SERIALIZABLE см. раздел «Свойства 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_ .
  • Отображение поля.
  • Привязка событий всплывающей подсказки и отображения редактора.

Вам потребуется выполнить следующие действия:

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. При создании заявки, пожалуйста, заполните всю необходимую информацию.