Visão geral sobre scripts

O App Maker possibilita a criação de aplicativos relativamente complexos sem programação. No entanto, às vezes são necessárias funcionalidades que os widgets e o editor de modelos não fornecem. O editor de scripts JavaScript do App Maker pode ajudar você nisso.

Há dois tipos de scripts no App Maker: scripts de cliente, que são executados nos navegadores dos usuários, e scripts de servidor executados nos servidores do App Maker. Mostramos aqui alguns exemplos do que é possível fazer com scripts no App Maker:

  • Realizar lógica e cálculos específicos do aplicativo.
  • Conectar-se a serviços da Web externos.
  • Criar verificações de permissões personalizadas.
  • E muito mais...

Scripts de cliente e servidor

Ainda que os scripts de cliente e de servidor executem JavaScript, eles diferem nos locais em que são usados e até mesmo como funcionam.

Fatos rápidos sobre o script de cliente

  • Os scripts de cliente são executados nos navegadores dos usuários. Eles podem acessar o DOM, o armazenamento local do navegador e muito mais.
  • Os scripts de cliente podem editar as propriedades do widget. O App Maker expõe widgets como objetos JavaScript, portanto, é possível alterar a aparência deles, eventos e outras propriedades programaticamente.
  • Scripts de cliente bloqueiam o navegador. Para manter os aplicativos responsivos, evite os cálculos complexos nos scripts de cliente.

  • APIs de cliente são assíncronas. Algumas chamadas de script de cliente são executadas fora de ordem. Veja o exemplo trabalhar com modelos de dados abaixo para mais detalhes.

  • Scripts de cliente não são seguros. Usuários avançados podem ver e alterar scripts de cliente com ferramentas do navegador. Não confie neles para segurança ou consistência de dados.

Fatos rápidos sobre o script de servidor

  • Scripts de servidor são executados no Apps Script. Eles podem acessar bancos de dados diretamente e usar APIs do Apps Script, como calendário, e-mail e muito mais.
  • Os scripts de servidor não mantêm o estado entre os pedidos. Eles são executados em servidores distribuídos, portanto, cada vez que você chamar um script, suas variáveis globais estarão vazias.
  • Scripts de servidor às vezes estão sujeitos a cotas. As chamadas para os serviços do Apps Script são limitadas por cotas diárias.
  • Scripts de servidor podem ser seguros. Ao contrário dos scripts de cliente, é possível confiar nos scripts de servidor para controlar o acesso a dados confidenciais. Use-os para auditoria e para reforçar a consistência dos dados.

Exemplos de script

A maneira mais fácil de entender a diferença entre os scripts de cliente e de servidor é por meio de exemplos. Os scripts abaixo são de um aplicativo de lista de tarefas que permite aos usuários criar várias listas, cada uma com diversas tarefas.

Cliente: interagir com páginas e widgets

Este script onClick para DeleteTodoListButton muda para uma página de confirmação quando um usuário clica no botão:

    app.showPage(app.pages.DeleteTodoListConfirmationView);
    

Cliente: implementar vinculações de propriedade

Este script é uma expressão de vinculação para a propriedade enabled do DeleteTodoListButton. Ele garante que o botão só será ativado quando não houver itens pendentes em uma lista. Assim, os usuários podem excluir apenas as listas sem tarefas pendentes.

    @datasource.item != null && @datasource.item.TodoItems.length == 0
    

Cliente e servidor: trabalhar com modelos de dados

Cliente:

Esse script cria e seleciona uma nova lista de tarefas. Primeiro, ele chama um script de servidor para criar um novo registro de lista, recarrega o modelo TodoList e, finalmente, seleciona a lista recém-criada.

    function onCreateTodoListClick() {
      var datasource = app.datasources.TodoList;
      google.script.run.withSuccessHandler(function(newKey) {

        // When created, redisplay todo lists.
        datasource.load(function() {

          // When reloaded, select new todo list.
          datasource.selectKey(newKey);
        });
      }).createTodoListWithItem();
    }
    

É possível perceber que o código não corresponde à ordem das operações acima. Isso porque esse script, assim como muitos scripts de cliente, é executado de forma assíncrona. O script não pode simplesmente executar createTodoListWithItem() depois load(), porque, sendo ambos assíncronos, não há garantia de que uma nova lista de tarefas será criada antes que a fonte de dados seja recarregada.

Em vez disso, createTodoListWithItem() chama load() com um callback que só é executado depois que um item da lista de tarefas é criado com sucesso. Saiba mais sobre scripts assíncronos e callbacks em Scripts de cliente.

Servidor:

Esse script de servidor é createTodoListWithItem(), chamado a partir do script de cliente acima. Ele acessa o banco de dados do aplicativo para criar uma nova lista de tarefas e um item para essa lista e, em seguida, retorna a Key da lista.

    function createTodoListWithItem() {
      // Automatically number todo lists for the user.
      var lock = LockService.getScriptLock();
      lock.waitLock(10000);
      var query = app.models.TodoList.newQuery();
      var allTodoLists = query.run();
      var todoList = app.models.TodoList.newRecord();
      var newListNumber = allTodoLists.length + 1;
      todoList.name = "My list " + newListNumber;
      app.saveRecords([todoList]);
      lock.releaseLock();

      // Create first todo item for user convenience.
      var todoItem = app.models.TodoItem.newRecord();
      todoItem.TodoList = todoList;
      app.saveRecords([todoItem]);
      return todoList._key;
    }
    

Scripts de servidor não salvam seus dados automaticamente, então o script chama saveRecords() para salvar as alterações no modelo. Lembre-se de fazer o mesmo ao escrever seus próprios scripts que criam ou editam registros.

O script também usa o bloqueio para garantir a consistência dos dados. Saiba mais sobre o bloqueio em Scripts de Servidor.

Servidor: segurança, auditoria e consistência de dados

Os scripts de servidor ajudam você a manter seus dados consistentes e seguros. O script acima usou o serviço de bloqueio para conseguir a atomicidade da consulta e criar operações.

Também é possível implementar permissões personalizadas usando exceções para proibir determinados eventos de modelo. Por exemplo, adicionar o seguinte ao evento onDelete() de um modelo impede a exclusão do registro:

    throw "Deletions now allowed";
    

Também é possível criar auditorias usando o gerenciador onCreate():

    var email = Session.getActiveUser().getEmail();
    record.setAudit("Created on " + new Date() + " by user " + email + "\n");
    

Cliente e servidor: buscar dados de outros URLs

Cliente:

Use um XMLHttpRequest ou o widget HtmlArea do App Maker para injetar um IFRAME.

Servidor:

Use o serviço de busca de URL do Apps Script.

Cliente: integrar bibliotecas JavaScript personalizadas

Há duas maneiras de carregar bibliotecas JavaScript externas, dependendo da biblioteca:

JSHint para validação de script

O App Maker oferece suporte a algumas diretivas do JSHint. Por exemplo, é possível usar a diretiva ignore para desativar o verificador estático de um bloco de código:

/* jshint unused: true, eqnull: false */
    var w = 3;   // Warning: w is defined but never used.
    alert(10 == null); // Warning: use '===' to compare with 'null'.

    /* jshint ignore:start */
    var y = 4;     // No warning.
    alert(10 == null); //  No warning.
    /* jshint ignore:end */

    var a = 5;   // Warning: a is defined but never used.
    alert(10 == null); // Warning: use '===' to compare with 'null'.
    

Para mais informações sobre o JSHint, consulte a documentação do JSHint.