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

В июле 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 см. в разделе Редактируемые и сериализуемые свойства .

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 содержит логику, рассмотрите возможность ее рефакторинга, чтобы она соответствовала путям обработки значений, описанным в разделе «Обработка значений» .

текст_

Мы рекомендуем вам никогда не получать доступ к свойству text_ вашего поля и не обновлять его напрямую. Вместо этого используйте функцию getText для доступа к читаемому пользователем тексту вашего поля и функцию setValue для обновления сохраненного значения вашего поля.

Дополнительные сведения о значении поля и его тексте см. в разделе «Анатомия поля» .

Получение помощи при обновлении

Что предоставить

При обращении за помощью лучше всего задавать конкретные вопросы:

Не рекомендуется: «Что не так с этим полем?»

Также не рекомендуется: «Помогите мне обновить это поле».

Рекомендуется: «Текст поля не обновляется должным образом».

Также необходимо предоставить ресурсы людям, помогающим вам. Эти файлы должны быть простыми для использования другими.

Не рекомендуется:

  • Изображения кода.
  • Неполный код.

Рекомендуемые:

  • Заполните код поля в текстовом формате.
  • Изображения гифок с плохим поведением в поле.
  • Действия по воспроизведению плохого поведения поля.
  • Версия Blockly, с которой вы обновляетесь.

Где разместить

Вопросы по обновлению публикуйте на форуме разработчиков Blockly .

Если вы уверены, что проблема связана с блочным ядром, вы также можете опубликовать проблему на блочном GitHub. Если вы решили опубликовать проблему, пожалуйста, заполните всю запрашиваемую информацию.