Criar e usar controladores personalizados
Objetivos de aprendizagem
Após concluir esta unidade, você estará apto a:
- Explicar o que é um controlador personalizado e descrever seus principais atributos.
- Criar uma classe de controlador personalizado.
- Utilizar um controlador personalizado em uma página do Visualforce.
Introdução aos controladores personalizados
Adicione um controlador personalizado a uma página do Visualforce fazendo referência ao nome da classe do controlador no atributo <apex:page>
controller
.
Quando sua página usa um controlador personalizado, você não pode usar um controlador padrão. As páginas usam um atributo diferente para definir o controlador personalizado.
- Abra o Developer Console e clique em File (Arquivo) | New (Nova) | Visualforce Page (Página do Visualforce) para criar uma nova página do Visualforce. Insira
ContactsListWithController
como nome da página.
- No editor, substitua qualquer marcação pelo seguinte.Quando você tentar salvar esta página, obterá um erro porque
<apex:page controller="ContactsListWithController"> <apex:form> <apex:pageBlock title="Contacts List" id="contacts_list"> <!-- Contacts List goes here --> </apex:pageBlock> </apex:form> </apex:page>
ContactsListWithController
ainda não existe. Não se preocupe, vamos corrigir isso a seguir.
Criar uma classe do Apex de controlador personalizado
Um controlador personalizado é apenas uma classe do Apex em que você escreve por conta própria usando o Developer Console.
Existem várias classes de sistema e de utilitários para ajudá-lo a escrever lógica de controlador personalizado, mas o único requisito para usar uma classe como controlador personalizado é que ela exista.
- Abra o Developer Console e clique em Arquivo | Nova Classe do Apex para criar uma nova classe do Apex. Insira
ContactsListWithController
no nome da classe.
No editor, substitua o código com o seguinte.
public class ContactsListWithController { // Controller code goes here }
Assim como com as páginas do Visualforce, você precisa salvar suas alterações no Apex quando elas ocorrem. Não é muito e isso não leva a nada ainda, mas faz o erro sumir na página do Visualforce.
- Volte para a página do Visualforce e salve-a novamente. A mensagem de erro deve sumir e a página será salva com êxito.
- Clique em Preview (Visualizar) para abrir uma visualização da página que você pode consultar enquanto faz alterações. Uma nova janela deve abrir mostrando os elementos de cabeçalho e barra lateral da página da Salesforce padrão, mas ainda sem conteúdo.
À primeira vista, esses dois novos itens que você criou não parecem muito interessantes. Mas mesmo que eles sejam 90% código de espaço reservado, os dois itens, a página do Visualforce e o controlador do Apex, estão vinculados um ao outro. Assim que você adicionar mais código ao controlador, sua página será capaz de usá-lo.
Ir além das noções básicas
Você deve ter notado que essa classe de controlador personalizado não herda de outra classe ou implementa uma interface que pretenda se adequar aos requisitos de um controlador do Visualforce. Mesmo os controladores complexos não fazem isso, já que não existe uma classe de onde herdar ou interface para implementar. Isso lhe dá liberdade para criar suas próprias classes e interfaces conforme vai aumentando a sua experiência com o Apex.
Adicionar um método para recuperar registros
Crie um método getter para executar uma consulta SOQL e retornar registros que você deseja exibir em sua página.
O objetivo principal da maioria dos controladores é recuperar dados para exibição ou tratar de atualizações de dados. Neste controlador simples, tudo o que você deve fazer é executar uma consulta SOQL básica que localiza registros de contato e disponibilizá-los na página do Visualforce.
- Na classe
ContactsListWithController
, substitua a linha de comentário// Controller code goes here
pelo código a seguir.Este código adiciona uma variável de membro privado, uma string chamadaprivate String sortOrder = 'LastName'; public List<Contact> getContacts() { List<Contact> results = Database.query( 'SELECT Id, FirstName, LastName, Title, Email ' + 'FROM Contact ' + 'ORDER BY ' + sortOrder + ' ASC ' + 'LIMIT 10' ); return results; }
sortOrder
e um método público,getContacts()
.sortOrder
é bem fácil de entender. É apenas o nome do campo para classificar os contatos.getContacts()
também é bastante simples, mas se você ainda não viu o Apex, pode ser difícil analisá-lo no início. O efeito do método é executar uma consulta SOQL para obter uma lista de registros de contato e retornar esta lista para o chamador do método. Quem seria esse chamador? A página do Visualforce, claro!
- Na página
ContactsListWithController
, substitua a linha de comentário<!-- Contacts List goes here -->
pela marcação a seguir.Quando salvar essa página, você verá uma tabela de informações de contato que lhe parece familiar.<!-- Contacts List --> <apex:pageBlockTable value="{! contacts }" var="ct"> <apex:column value="{! ct.FirstName }"/> <apex:column value="{! ct.LastName }"/> <apex:column value="{! ct.Title }"/> <apex:column value="{! ct.Email }"/> </apex:pageBlockTable>
A marcação da página ContactsListWithController
deve ter uma aparência bem familiar. Exceto o atributo controller
da marca <apex:page>
, é basicamente o mesmo código que você usaria para criar a página com o controlador padrão.
A diferença está no que acontece quando a expressão {!contacts }
é avaliada. Nessa página, o Visualforce traduz a expressão em uma chamada para o método getContacts()
do seu controlador. O método retorna uma lista de registros de contato, que é exatamente o que <apex:pageBlockTable>
está esperando.
O método getContacts()
é chamado de método getter e é um padrão geral, em que {!someExpression }
em sua marcação do Visualforce se conecta automaticamente a um método chamado getSomeExpression
() em seu controlador. Essa é a maneira mais simples de fazer com que a sua página acesse os dados de que necessita para exibição.
Adicionar um novo método de ação
Cria métodos de ação no controlador personalizado para responder às entradas do usuário na página.
Mostrar os dados é ótimo, mas responder às ações do usuário é essencial para qualquer aplicativo da web. Com o controlador personalizado, é possível criar quantas ações personalizadas você quiser para dar suporte a uma página. Para isso, escreva métodos de ação que respondam à atividade do usuário.
- Na classe
ContactsListWithController
, abaixo do métodogetContacts()
, adicione os dois métodos a seguir.Esses dois métodos alteram o valor da variável privadapublic void sortByLastName() { this.sortOrder = 'LastName'; } public void sortByFirstName() { this.sortOrder = 'FirstName'; }
sortOrder
.sortOrder
é usado na consulta SOQL que recupera os contatos e modificarsortOrder
alterará a ordem dos resultados.
- Na página
ContactsListWithController
, substitua as duas marcas<apex:column>
dect.FirstName
ect.LastName
pelas marcações a seguir.Embora a aparência permaneça a mesma, agora, se você clicar nos cabeçalhos das colunas Nome e Sobrenome, elas mudarão a ordem de classificação da lista de contatos. Perfeito!<apex:column value="{! ct.FirstName }"> <apex:facet name="header"> <apex:commandLink action="{! sortByFirstName }" reRender="contacts_list">First Name </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.LastName }"> <apex:facet name="header"> <apex:commandLink action="{! sortByLastName }" reRender="contacts_list">Last Name </apex:commandLink> </apex:facet> </apex:column>
A nova marcação adiciona dois componentes aninhados a cada um dos componentes <apex:column>
. <apex:column>
por si só tem um cabeçalho de texto simples, mas queremos tornar o cabeçalho clicável. <apex:facet>
nos permite definir o conteúdo do cabeçalho da coluna para o que quisermos. E nós queremos um link que chame o método de ação certo. Esse link é criado usando o componente <apex:commandLink>
, com o atributo action
definido como uma expressão que faz referência ao método de ação em nosso controlador. (Observe que os métodos de ação, ao contrário dos métodos getter, recebem o mesmo nome que a expressão que os menciona.)
Quando alguém clica no link, ele desencadeia o método de ação no controlador. O método de ação altera a variável particular da ordem de classificação e a tabela é renderizada novamente. Quando isso acontece, {!contacts }
é reavaliado, o que volta a executar a consulta com qualquer ordem de classificação definida. O resultado final é uma tabela reclassificada na ordem solicitada pelo clique do usuário.
Ir além das noções básicas
O texto do cabeçalho referente às colunas Nome e Sobrenome é embutido na marcação. Mas o que acontece se nem todos os usuários falarem inglês? A interface de usuário padrão do Salesforce conta com versões traduzidas dos nomes dos campos de todos os objetos padrão, e você pode inserir suas próprias traduções dos objetos personalizados. Como fazer para acessá-los? Em vez do texto simples, tente esta marcação: <apex:outputText value="{!$ObjectType.Contact.Fields.FirstName.Label }"/>
. Esse é o jeito certo de mencionar o rótulo de um campo, mesmo que toda a sua organização use o mesmo idioma, porque isso atualiza automaticamente o nome do campo caso ele seja alterado.
Quero saber mais...
Controladores personalizados e a linguagem Apex permitem que você faça basicamente tudo que quiser nas suas páginas do Visualforce.
Os métodos getter retiram dados de seu controlador para a sua página. Há métodos setter correspondentes que deixam você enviar valores da página de volta ao seu controlador. Assim como os métodos getter, você deve prefixar seus setters com “set” e, fora isso, eles são apenas métodos que assumem um argumento.
Uma alternativa aos métodos getter e setter é o uso das propriedades Apex. Propriedades são um tipo de combinação de uma variável com métodos getter e setter, com sintaxe que os agrupa de maneira mais clara. Uma propriedade simples que faça referência a um objeto personalizado pode ser declarada da forma a seguir.
public MyObject__c myVariable { get; set; }
Propriedades poderão ser públicas ou privadas, somente leitura ou até somente gravação se get ou set forem omitidos. Você poderá criar implementações para os métodos get ou set quando quiser realizar lógica adicional além de simplesmente salvar e recuperar um valor.
As propriedades são um recurso geral do Apex, e não específicas do Visualforce. Apex é uma linguagem de programação completa e, além de ser o parceiro natural na criação de páginas complexas do Visualforce, é usada em vários outros contextos de desenvolvimento da Lightning Platform. Veja os tópicos de Apex mais adiante e os recursos no final dessa página para conhecer várias maneiras de usar completamente o Apex.
O ciclo de vida de uma solicitação e resposta do Visualforce pode parecer complexo à primeira vista. Mais especificamente, é importante entender que não há uma ordem específica para chamar getters ou setters (ou propriedades, se você usá-las) e, portanto, você não deve introduzir dependências de ordem de execução entre eles. Isso é visto com maiores detalhes nas seções pertinentes do Guia para desenvolvedores do Visualforce, especialmente o capítulo Controladores personalizados e extensões de controlador.
Recursos
- Guia do desenvolvedor do Visualforce: Creating Your First Custom Controller
- Guia do desenvolvedor do Visualforce: Custom Controllers and Controller Extensions
- Apex Developer Guide
- Blog de desenvolvedores do Salesforce: Modelo do Apex: Visualforce Controller
- Blog de desenvolvedores do Salesforce: A Real Controller for Visualforce Charting
- Guia do desenvolvedor do Visualforce: Componente apex:outputLink
- Guia do desenvolvedor do Visualforce: Componente apex:repeat