Script de cliente

Os scripts do cliente são executados nos computadores dos usuários, nos ambientes de execução de JavaScript de seus navegadores. Eles são ótimos para manipular eventos da IU e alterar elementos DOM e propriedades de widgets.

Os scripts de cliente também podem acionar interações com o servidor por meio das APIs do App Maker. Por exemplo, os scripts de cliente podem buscar e modificar dados de um banco de dados ou invocar scripts de servidor.

Operações assíncronas e funções de retorno de chamada

Os scripts de cliente podem ser executados de forma assíncrona no App Maker para manter a interface de usuário (IU) do aplicativo responsiva. Em alguns aplicativos de navegador, quando uma operação precisa aguardar um recurso externo, todo o aplicativo aguarda com ela. A IU aguarda também e não é responsiva.

Com o código assíncrono, a IU e outras operações do aplicativo permanecem responsivas, mas seus scripts podem não ser executados na ordem em que são gravados. Para executar um script após a conclusão de uma operação assíncrona, como o código que manipula os resultados da operação, use uma função de retorno de chamada.

Funções de retorno de chamada são scripts de cliente que são executados quando as operações são concluídas. É possível especificar funções que são executadas quando a operação é bem-sucedida, ou um objeto que executa funções diferentes para cenários de sucesso e falha.

Funções de retorno de chamada somente de sucesso

Quando você inclui uma função de retorno de chamada somente de sucesso, ela é executada somente se a operação for bem-sucedida. Se a operação falhar, nada acontece. Como um exemplo simples, crie um registro de forma assíncrona com createItem() e envie um alerta sobre ele:

widget.datasource.createItem(function (record) {
  alert('Record with ID ' + record.id + ' was created in the database.');
});

Funções de retorno de chamada de sucesso e falha

Como uma extensão do caso anterior, use esse método para ser notificado de falhas e para executar relatórios de erros, limpeza ou reversões.

widget.datasource.createItem({
  success: function (record) {
    alert('Record with ID ' + record.id + ' was created in the database.');  // executes if record was created
  },
  failure: function (error) {
    console.info("No new record for you!"); // executes if record wasn't created
  }
});

Nenhuma função de retorno de chamada

Se você omitir o callback ou passar nulo como o callback, o código continuará sem aguardar a conclusão da operação. Por exemplo:

    widget.datasource.createItem();
    console.info("warning, record is probably not yet created!");

Solução de problemas

Veja a seguir algumas estratégias para solucionar problemas de scripts de cliente para localizar e corrigir erros:

  • Encontre erros de sintaxe no editor de script. O editor de scripts do App Maker avisa automaticamente sobre problemas de sintaxe enquanto você digita. Verifique se há rótulos de aviso à esquerda dos números de linha do seu script. Os avisos pegam erros comuns como parênteses esquecidos.

  • Encontre erros de ambiente de execução no console JavaScript do seu navegador. Abra uma instância de visualização ou uma versão implementada do seu aplicativo e abra o console JavaScript do seu navegador. No Chrome, abra o console do JavaScript pressionando Ctrl+Shift+j ou Alt-Cmd-j. Algumas exceções de ambiente de execução comuns são declarações null cancelando a referência ou throw não capturada. É possível adicionar declarações debugger; ao script para parar a execução dele e identificar a área do problema (DevTools precisa estar aberto para que instruções debugger; entrem em vigor). Para ver mais instruções de depuração, consulte Introdução à depuração de JavaScript no DevTools do Chrome.

  • Siga a execução do seu script com registros e alertas. Use a função console.log() integrada do navegador para enviar registros para o console JavaScript. Como alternativa, use alert() para abrir uma caixa de alerta que interrompe a execução do seu script até que você o dispense.

Exemplos de script de cliente

Usar scripts em expressões de vinculação

Use o JavaScript para executar cálculos em expressões de vinculação. Por exemplo, a expressão a seguir na propriedade enabled de um botão o desativa se o campo Name estiver em branco ou o campo Age tiver um valor menor que 18:

(@widget.parent.children.NameTextBox.value).length != 0 &&
@widget.parent.children.AgeTextBox.value >= 18

O analisador do App Maker primeiro resolve as expressões de vinculação, que começam com @, para encontrar o valor de Name e Age. Em seguida, ele substitui esses valores pelas expressões e avalia o restante do JavaScript.

Os parênteses na primeira linha indicam o final da expressão de vinculação. Sem eles, o App Maker observaria a propriedade length em busca de alterações, em vez da propriedade value.

Chamar um script de servidor

Chame scripts de servidor de seus scripts de cliente usando as APIs do App Maker. Chamar scripts de servidor é uma operação assíncrona, portanto, é necessário usar um callback para processar o resultado do script.

O script de cliente abaixo chama um script de servidor para receber o preço atual das ações do Google e, em seguida, exibe o resultado como uma mensagem de alerta usando um callback.

Script de cliente:

function getGoog() {
  google.script.run.withSuccessHandler(function(result) {
    var quote = result.trim().split("\n").pop().split(",").pop();
    alert(quote);
  }).getGoogleStockInfo();
}

Script de servidor:

function getGoogleStockInfo() {
  var url = "https://www.google.com/finance/getprices?f=d,c&q=GOOG";
  var response = UrlFetchApp.fetch(url);
  return response.getContentText();
}

Carregar dinamicamente scripts externos

É possível carregar vários scripts de terceiros de forma síncrona com Bibliotecas externas de JavaScript, mas alguns exigem um pouco mais de trabalho. As bibliotecas que exigem um parâmetro de callback, como a biblioteca de cliente de APIs do Google, precisam ser carregadas dinamicamente, adicionando um script a Settings > General > onAppStart.

O script a seguir carrega a biblioteca do Google+:

// Suspends app loading until after the Google Client API loads.
loader.suspendLoad();
// Defines a callback function, for the client API. It must be global,
// so it's explicitly attached to the window object.
window.OnGapiClientLoad = function() {
  // Uses the Google Client API to load the Google+ library.
  gapi.client.load("plus", "v1", function() {
    // Continues loading the app once Google+ loads.
    loader.resumeLoad();
  });
};

var script = document.createElement("script");
script.setAttribute("type", "text/javascript");

// Specifies the name of the callback function in the "onload"
// parameter of the URL.
var url = "https://apis.google.com/js/client.js?onload=OnGapiClientLoad";
script.setAttribute("src", url);

document.getElementsByTagName("head")[0].appendChild(script);

Chamar APIs do Google

Este último exemplo é um pouco mais profundo e dá a você uma ideia de como é um script real do App Maker. Ele faz uso de uma API de JavaScript do Google.

O script exibe um mapa do Google em uma página e o atualiza com base na entrada do usuário. O script funciona com uma página denominada Map que contém os widgets a seguir:

  • Dois campos de texto, chamados Street e Zip
  • Uma HtmlArea de 200x200 chamada MapDiv que tem um evento onAttach que chama loadMaps()
  • Um botão, com um gerenciador onClick() que chama updateMap()

Script

var map;
var geocoder;
var marker;

// Called by loadMaps() to set up widgets.
function createMap() {
  var div = app.pages.Map.descendants.MapDiv.getElement();
  map = new google.maps.Map(div, {
    center: new google.maps.LatLng(-34.397, 150.644),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    zoom: 10,
  });
  geocoder = new google.maps.Geocoder();
  marker = new google.maps.Marker({map: map});
}

// Returns an address string from Street and Zip text fields.
function getAddress() {
  var page = app.pages.Map;
  var street = page.descendants.Street.value;
  var zip = page.descendants.Zip.value;
  return street + ", " + zip;
}

// Positions the map at the given location coordinates.
function showLocation(locations, status) {
  if (locations.length > 0) {
    var latLng = locations[0].geometry.location;
    map.panTo(latLng);
    marker.setPosition(latLng);
  }
}

// Sets up the Google Maps library.
function loadMaps() {
  google.load("maps", "3", {callback: createMap});
}

function updateMap() {
  geocoder.geocode({address: getAddress()}, showLocation);
}

Destaques do script:

  • O MapDiv usa seu gerenciador onAttach() para configurar a API do Google Maps.
  • O script usa getAddress() para acessar a entrada do usuário puxando dados dos campos Rua e CEP.