Eventos

Cada mudança no espaço de trabalho aciona um evento. Esses eventos descrevem completamente o estado anterior e posterior de cada mudança.

Ouvir eventos do espaço de trabalho

Os espaços de trabalho têm métodos addChangeListener e removeChangeListener que podem ser usados para detectar o fluxo de eventos. Um exemplo é a geração de código em tempo real. Outro exemplo é a demonstração do limite máximo de blocos. Como é comum, nenhum desses dois exemplos se importa com o evento acionado. Eles simplesmente analisam o estado atual do espaço de trabalho.

Um listener de eventos mais sofisticado analisaria o evento acionado. O exemplo a seguir detecta quando o usuário cria o primeiro comentário, emite um alerta e para de ouvir para que nenhum outro alerta seja acionado.

function onFirstComment(event) {
  if (event.type == Blockly.Events.BLOCK_CHANGE &&
      event.element == 'comment' &&
      !event.oldValue && event.newValue) {
    alert('Congratulations on creating your first comment!')
    workspace.removeChangeListener(onFirstComment);
  }
}
workspace.addChangeListener(onFirstComment);

Para detectar eventos que acontecem em um menu suspenso, um listener pode ser adicionado ao espaço de trabalho dele.

var flyoutWorkspace = yourWorkspace.getFlyout().getWorkspace();
flyoutWorkspace.addChangeListener(onFirstComment);

Ouvir eventos de blocos

Os blocos podem ter funções de listener de mudança que são chamadas em qualquer alteração no espaço de trabalho, incluindo aquelas não relacionadas ao bloco. Elas geralmente são usadas para definir o texto de aviso do bloqueio ou uma notificação semelhante do usuário fora do espaço de trabalho.

A função é adicionada chamando Block.setOnChange com uma função e pode ser feita durante a inicialização ou por uma extensão JSON, se você planeja usá-la em todas as plataformas.

JSON

{
  // ...,
  "extensions":["warning_on_change"],
}

Blockly.Extensions.register('warning_on_change', function() {
  // Example validation upon block change:
  this.setOnChange(function(changeEvent) {
    if (this.getInput('NUM').connection.targetBlock()) {
      this.setWarningText(null);
    } else {
      this.setWarningText('Must have an input block.');
    }
  });
});

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.setOnChange(function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    });
  }
}

Também é possível definir a propriedade onchange diretamente no bloco:

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.onchange = function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    };
  }
}

O sistema chama a função, transmitindo o evento de mudança. Dentro da função, this se refere à instância do bloco.

Como a função é chamada em qualquer alteração, se usada, os desenvolvedores precisam garantir que o listener seja executado rapidamente. Também é preciso ter cuidado com as mudanças no espaço de trabalho que podem ser transmitidas em cascata ou retornar ao listener.

Confira os blocos controls_flow_statements, logic_compare e procedures_ifreturn para conferir exemplos.

Os campos editáveis têm listeners de evento próprios para validação de entrada e causam efeitos colaterais.

Tipos de evento

Consulte a documentação de referência para informações sobre eventos individuais.

Demonstração

Para conferir um exemplo de coisas legais que você pode fazer com eventos, confira a demonstração do espelho. Esta demonstração tem dois espaços de trabalho do Blockly que são mantidos sincronizados usando eventos.