Eventos

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

Detectar 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 costuma acontecer, nenhum desses dois exemplos se importa com o evento acionador. Eles apenas analisam o estado atual do espaço de trabalho.

Um listener de eventos mais sofisticado analisaria o evento acionador. O exemplo a seguir detecta quando o usuário cria o primeiro comentário, emite um alerta e para de detectar 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 dentro de um menu flutuante, um listener pode ser adicionado ao espaço de trabalho do menu.

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

Detectar eventos de blocos

Os blocos podem ter funções de listener de mudanças que são chamadas em qualquer mudança no espaço de trabalho (incluindo aquelas não relacionadas ao bloco). Elas geralmente são usadas para definir o texto de aviso do bloco ou uma notificação de usuário semelhante 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 JSON extensão 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 mudança, 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 em cascata ou em loop para o listener.

Consulte os blocos controls_flow_statements, logic_compare e procedures_ifreturn para exemplos.

Observação: os campos editáveis têm listeners de eventos próprios para validação de entrada e efeitos colaterais.

Tipos de evento

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

Demonstração

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