Aprender conceitos de codificação

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:
  • Mapear conceitos fundamentais, como controladores e solicitações, do Visualforce para os componentes do Aura.
  • Evitar o principal erro de sintaxe no código dos componentes do Aura.
  • Descrever a vantagem de componentes frouxamente acoplados e a maneira como o acoplamento frouxo é realizado.

Conceito: Controladores

Finalmente! Um conceito com um nome que você reconhece!

Deslizador! Apesar do nome familiar, esta é uma área onde sua experiência com o Visualforce não se aplica aos componentes do Aura. Um dos recursos principais do Visualforce é o Controlador padrão. Definindo um único atributo para uma página, você pode vincular essa página a um tipo de sObject e obter um monte de comportamentos automáticos — por exemplo, ler e escrever dados de registro — sem escrever nenhum código. Com o Controlador padrão, mesmo aqueles que não são programadores podem criar páginas do Visualforce totalmente personalizadas. Não há nada similar para os componentes do Aura. Para se criar um componente que funcione com registros é necessário escrever código.

E os controladores personalizados do Visualforce? Eles também requerem que você escreva seu próprio código. Não podem ser tão diferentes assim dos controladores dos componentes do Aura, certo? Deslizador!

Primeiramente, lembre-se de que os controladores do Visualforce são executados no lado do servidor, enquanto os controladores dos componentes do Aura são executados no lado do cliente. E às vezes também no lado do servidor. Os controladores do Visualforce são escritos em Apex, enquanto os controladores dos componentes do Aura são escritos em JavaScript. E às vezes também em Apex.

Arquitetura do controlador do Visualforce Arquitetura do controlador de componentes do Aura
Arquitetura do controlador do Visualforce Arquitetura do controlador dos componentes do Lightning

Como você pode ver na ilustração, os dois são arquiteturalmente diferentes. Essa diferença, o controlador do lado do cliente, afeta o código que você escreve. Seu código do controlador do componente do Aura é executado no cliente, enquanto os dados são armazenados no servidor. Na ausência de armazenamento em cache, toda vez que você quiser novos dados, você faz algum tipo de solicitação do servidor. Esse é um código que você talvez não estivesse escrevendo para seus controladores do Visualforce. Além disso, solicitações remotas são escritas em estilo assíncrono, baseado em retorno de chamada, o que pode ser muito diferente de seu código do controlador existente.

Além disso, muitos controladores e extensões personalizados do Visualforce usam as classes do Apex StandardController ou StandardSetController, para estender o comportamento integrado em vez de substituí-lo. Infelizmente, elas são estritamente vinculadas ao Visualforce. Você não pode reutilizá-las em seu código do controlador do lado do servidor dos componentes do Aura. É mais código que você precisa escrever você mesmo.

Escada! Mas temos boas notícias. Se você criar suas páginas do Visualforce usando JavaScript Remoting e métodos Apex @RemoteAction, você já escreve seu código do controlador de uma maneira que pode ser altamente reutilizável para componentes do Aura. Você precisa atualizar o código existente, mas já deu o salto para a nova arquitetura.

Escada! Finalmente, vamos terminar com as notícias realmente boas. O Lightning Data Service (LDS) só está disponível com os componentes do Aura. Ele é o que os componentes do Aura têm de mais próximo a um controlador padrão. Ele requer que você escreva algum código. Não tanto quanto um controlador simples, mas algum. Mas o LDS é muito mais avançado e inclui armazenamento em cache integrado, notificação de atualização e outros recursos muito legais. Depois que você mudar, não vai mais querer voltar atrás. Consulte a seção de Recursos para saber mais sobre o LDS.

Conceito: Ações

No Visualforce, uma ação é um método de controlador que retorna uma PageReference no final. Normalmente vinculada a um botão ou a um link, uma ação representa o trabalho que o usuário quer que o aplicativo execute, seguida pela navegação para uma página seguinte ou de resultados, ou talvez apenas de volta para a “página inicial”. Por exemplo, um botão editar chama um método de ação que carrega os dados de um registro, depois navega até uma página com um formulário de edição.

Escada! As ações dos componentes do Aura são similares. Ações são funções que você escreve em JavaScript e vincula a elementos da interface de usuário. Finalmente, é hora da escada!

Mas espere. Existem diferenças importantes, e se você não as perceber, vai descer pelo deslizador abaixo em vez de subir a escada.

Primeiramente, perceba que as ações não são chamadas diretas de função ou método, nem nos componentes do Visualforce nem do Aura. Você não as chama, a estrutura as invoca quando apropriado. Até aí, tudo igual.

Porém, no Visualforce suas ações são métodos definidos em uma classe do Apex. Você obtém algum tipo de infraestrutura de linguagem em torno de seu método, como variáveis de instância e métodos de instância e classe.

Deslizador! As ações dos componentes do Aura não são definidas em uma classe. Em vez disso, são definições de função declaradas no lado (direito) do valor de elementos em um objeto JavaScript em notação de literal de objeto contendo pares nome-valor. Aqui está um exemplo trivial:
({
    myAction : function(component, event, helper) {
        // add code for the action
    },
})

Essa diferença no estilo de declaração possui consequências sintáticas e estruturais. No lado da sintaxe, observe aquela vírgula após a declaração da função (na linha 4). Separe manipuladores de ação com vírgulas! No Apex isso seria um erro de sintaxe. Na notação de literal de objeto, a falta de uma vírgula entre duas definições de ação é o erro de sintaxe. Esteja ciente de que a falta de uma vírgula pode ser um erro difícil de perceber, então adquira o hábito de sempre separar seus manipuladores de ação com vírgulas.

Dica

Dica

Se estiver usando um editor externo que permita plug-ins, considere adicionar uma ferramenta de validação de JavaScript, como a ESLint, a seu ambiente. Como esse é um erro de sintaxe de JavaScript, praticamente qualquer ferramenta de estilo lint vai identificá-lo antes que você tenha passado mais de duas linhas do erro.

As diferenças estruturais impedem que o código do controlador acesse outras funções ou valores dentro do recurso do controlador. Você não pode declarar métodos auxiliares no controlador, não pode criar propriedades estáticas ou de instância e assim por diante. Em vez disso, coloque código reutilizável em um auxiliar associado e armazene valores de instância como atributos em seu componente. Vamos discutir essa última parte mais detalhadamente.

Conceito: Propriedades vs. Atributos vs. “Expandos”

As propriedades do Apex são (de fato) variáveis de instância com uma lógica personalizada por trás. Quando você as define em um controlador ou uma extensão do Visualforce, as expressões em uma página podem utilizá-las. Embora obter e definir uma propriedade de controlador supostamente não deva ter efeitos colaterais (o termo em ciência da computação é idempotente), as propriedades podem chamar métodos auxiliares para compartilhar ou abstrair a lógica por trás delas. Propriedades são realmente úteis — e comuns — em controladores do Visualforce.

Embora você talvez queira criar propriedades similares no arquivo do controlador JavaScript do seu componente do Aura, isso não é possível. Você pode tentar adicioná-las ao auxiliar, o que talvez pareça funcionar. Contudo, o auxiliar é um singleton, compartilhado em todas as instâncias de seu componente. Ele é mais como uma variável de estática de classe, então você não pode usá-lo para salvar o estado de um componente individual.

Então, o que você faz?

Atributos dos componentes

Se precisar acessar o valor em uma expressão na marcação de seu componente, use um atributo de componente. Um atributo de componente é declarado assim.
<aura:attribute name="myAttribute" type="Integer"/>
Atributos de componente requerem, no mínimo, um nome e um tipo de dados. (Existem atributos opcionais para os padrões e assim por diante.) Faça referência ao atributo na marcação usando sintaxe de expressão padrão.
{!v.myAttribute}
(Teremos mais a dizer sobre expressões e sintaxe de expressão no próximo módulo.)

Obtenha e defina o valor do atributo em seu código JavaScript do controlador usando (surpresa!) os métodos get e set. Utilizar as funções get e set para obter e definir os valores do atributo de componente

Os métodos get e set são funções disponíveis no parâmetro do componente passados para a função do manipulador de ação myAction.
({
    myAction : function(component, event, helper) {
        var counter = component.get("v.myAttribute");
        counter++;
        component.set("v.myAttribute", counter);
    },
})
Aqui get (linha 3) recupera o valor do atributo de componente myAttribute e atribui o valor à variável de counter local. counter é aumentada e, em seguida, set (linha 5) atualiza o atributo de componente.

Se não quiser que outros componentes mexam no valor do atributo de componente, torne o atributo private. Caso contrário, o atributo se torna parte da API pública de seu componente.

Expandos JavaScript e atributos privados

Atributos, com sua “dança” de get/set, por vezes podem parecer “cerimoniosos” para os desenvolvedores de Visualforce. Se você for versado em JavaScript, pode tentar usar uma particularidade do JavaScript e definir um valor na instância do componente de dentro de uma função de ação.

component._myExpando = "A new string variable";

Esse expando, criado instantaneamente, se torna parte da instância de seu componente. Ele parece uma bela variável de instância privada leve.

O problema é que expandos criam uma oportunidade para bugs sutis e vazamentos de memória. Embora funcionem, também tendem a causar problemas, e por essa razão recomendamos não usá-los. A abordagem recomendada é criar um atributo de componente e definir seu nível de acesso como private. (Também recomendamos prefixar os nomes de atributos privados com um sublinhado (por exemplo, _myAttribute), para deixar óbvio que são variáveis privadas.)

Conceito: Chamadas de método vs. Eventos

Vamos terminar este módulo com um último Grande conceito.

Suas páginas do Visualforce (provavelmente) são executadas com base em métodos. Expressões, propriedades e ações se resumem todas a chamadas de função. Chamadas de função (ou método) são fáceis de ver — você as declara na classe do Apex de seu controlador. É fácil seguir a ordem de execução e raciocinar sobre o comportamento. (Sim, “fácil” é um termo relativo. Calma que eu vou explicar.)

Chamadas de método também representam o rígido acoplamento entre as partes de seu aplicativo. Sua página é rigidamente acoplada a seu controlador e suas extensões, que, por sua vez, podem ser rigidamente acoplados a outras classes do Apex. As relações entre as peças, embora fáceis de acompanhar, são também potencialmente frágeis ou difíceis de serem reutilizadas.

Os componentes do Aura foram projetados para lidar com muitas dessas limitações do Visualforce. Em particular, componentes que são (ou que se pretende que sejam) frouxamente acoplados. O mecanismo para esse acoplamento frouxo é eventos.

Você pode pensar em uma chamada de método como uma “linha contínua” ligando o chamador com o receptor da chamada, como um fio físico. Um interruptor é ligado em uma extremidade e uma luz se acende na outra. Com fiação física, é possível ter múltiplos dispositivos no mesmo circuito — mas quando você quer a luz acesa no corredor, ela também se acende no closet. É a mesma coisa com software: Quanto mais você reutiliza as partes rigidamente acopladas de um sistema, mais efeitos colaterais você obtém e mais difícil fica encaixar novas peças.

Usar eventos para se comunicar entre os componentes do Aura cria conexões “sem fio”. Ligar um interruptor (acionar um evento) é como um sinal de rádio. Se houver alguém (outro componente) lá fora sintonizado naquela frequência (que tenha um manipulador para aquele evento), ele pode agir ao receber o sinal. Mas você, o operador solitário do sistema sem fio, não sabe se tem alguém lá fora sintonizado na mesma frequência. Da mesma forma, você escreve seu componente para que ele se comporte da maneira correta, independentemente de seu evento ser recebido e tratado ou não.

Nossa metáfora está ficando forçada, então vamos concluir com dois conselhos específicos.

  • Dê a devida oportunidade e algum tempo aos princípios de composição e acoplamento frouxo e você crescerá como desenvolvedor. A abordagem é diferente daquela à qual você está habituado com o Visualforce. Alguns diriam que é mais difícil, mas nós achamos que é uma questão de aprendizado e experiência.
  • Não trate métodos da mesma maneira que faria no Visualforce. Você descobrirá inevitavelmente que pode publicar e chamar métodos em seus componentes do Aura. É tentador, quando você se depara com um desafio de design, recorrer àquilo que você conhece. Resista à tentação. Os métodos dos componentes do Aura têm seus usos apropriados. Utilize-os quando são a ferramenta certa para o trabalho. Mas não faça deles uma solução para todos os seus problemas.