Como atualizar um campo personalizado

Em julho de 2019 (versão 2.20190722) uma API de campos mais codificados foi adicionada. Ele tem como objetivo ser o mais compatível possível com versões anteriores. Isso significa que, se você tivesse criado antes de julho de 2019, ele provavelmente continuará funcionando. Antes de decidir se o campo personalizado precisa passar por upgrade, leia na seção Áreas de perigo e faça um teste minucioso do campo.

Porque não havia padronização entre os campos antes de julho de 2019. é complicado cobrir todas as mudanças que um desenvolvedor pode precisar fazer. Este documento tenta cobrir todas as alterações prováveis, mas, se ele não abordar algo em que você tem interesse, leia a seção sobre recebendo assistência para upgrade.

Áreas de perigo

Áreas perigosas são lugares conhecidos onde a API mudou, e seu campo pode ser de quebrar.

Blockly.Field.register

Os campos não são mais registrados por Blockly.Field.register();. Há agora um namespace fieldRegistry que gerencia o registro.

Blockly.Field.register('my_field_name', myFieldClass);

O resultado é:

Blockly.fieldRegistry.register('my_field_name', myFieldClass);

setText

A função setText não é mais chamada pelo núcleo do Blockly. Portanto, se o setText contém lógica. Ela precisará ser movida para processamento de valores o pacote de funções getText e as funções de renderização (dependendo do que exatamente a função setText está fazendo).

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;
};

O resultado é:

CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
  if (typeof newValue != 'string') {
    return null;
  }
  return newValue;
};

CustomFields.UpgradeField.prototype.getText = function() {
  return  'prefix' + this.value_;
}

O Blockly gerencia automaticamente:

  • Verificar se o novo valor é diferente do antigo.
  • Atualizando o valor.
  • Disparando eventos de alteração.
  • Rerenderizando o campo.

Você precisará lidar com o seguinte:

.

Os upgrades recomendados são lugares onde a API do campo foi alterada, mas se você optar por não fazer alterações, seu campo provavelmente ainda funcionará.

SÉRIE

Para mais informações sobre as propriedades EDITABLE e SERIALIZABLE, consulte Propriedades editáveis e serializáveis.

CustomFields.UpgradeField.prototype.SERIALIZABLE = true;

O aviso abaixo pode ser ignorado, mas é possível resolvê-lo definindo o SERIALIZABLE :

Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.

O aviso acima significa que o Blockly acredita que você quer campo a ser serializado (porque a propriedade EDITABLE é verdadeira), mas não é possível ter certeza até definir a propriedade SERIALIZABLE. Se você escolher deixe isso em paz, tudo funcionará corretamente e seu campo será serializados, mas você receberá avisos do console.

size_.width

this.size_.width = 0;

O resultado é:

this.isDirty_ = true;

O aviso abaixo pode ser ignorado, mas ele pode ser resolvido definindo a isDirty_ em vez de size_.width:

Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.

O aviso acima significa que o Blockly detectou que você está usando um método antigo para renderizar novamente uma campo, e gostaria que você usasse o novo método.

Para mais informações sobre a propriedade isDirty_, consulte isDirty_.

init

A função init foi transformada em um modelo função para de redução do código duplicado em subclasses.

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());
};

O resultado é:

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_);
};

Isso significa que o bloqueio agora processa automaticamente:

  • Verificando se o campo já foi inicializado.
  • Criando o fieldGroup_.
  • Renderizando o campo.
  • Dica de vinculação e exibição de eventos do editor.

Você precisará lidar com o seguinte:

.

onMouseDown_

CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
  // ...
};

O resultado é:

CustomFields.UpgradeField.prototype.showEditor_ = function() {
  // ...
}

Recomendamos substituir a função showEditor_ para processar dados em vez da função onMouseDown_, já que ela permite que a entrada transmita pelo sistema de gestos.

Para mais informações sobre editores, consulte Editores.

setValue

A função setValue agora é um modelo função para de redução do código duplicado em subclasses. Se a função setValue tiver lógica, considere refatorá-lo para que se ajuste aos caminhos de tratamento de valores descritos em Processamento de valores.

text_

Recomendamos que você nunca acesse ou atualize a propriedade text_ dos seus no campo correspondente. Em vez disso, use o método Função getText para acessar o texto legível pelo usuário do seu campo e a Função setValue para atualizar o valor armazenado do campo.

Para mais informações sobre o valor de um campo em comparação com o texto dele, consulte Anatomia de um campo.

Como receber assistência para upgrade

O que fornecer

Ao pedir ajuda, é melhor fazer perguntas específicas:

Não recomendado: "O que há de errado com este campo?"

Também não recomendado: "Ajude-me a atualizar este campo".

Recomendado: "O texto do campo não está sendo atualizado corretamente."

Também é necessário fornecer recursos às pessoas que ajudam você. Esses devem ser fáceis de usar.

Não recomendado:

  • Imagens do código.
  • Código incompleto.

Recomendado:

  • Preencha o código do campo em formato de texto.
  • Imagens de GIFs de mau comportamento de campo.
  • Etapas para reproduzir o mau comportamento de campo.
  • A versão do Blockly de onde você está fazendo upgrade.

Onde postar

Perguntas pós-upgrade no desenvolvedor do Blockly fórum.

Se você tiver certeza de que o problema é com o núcleo bloqueado, também publicar um problema no GitHub. Se você decidir postar um problema, preencha todos informações solicitadas.