Olá, desbravadores! Veremos hoje um tema bem interessante, o uso de flex com alguma tecnologia server-side. Neste exemplo usarei PHP, mas nada impede que seja usada outra tecnologia como ASP, JSP ou outra.
Para ilustrar, iremos construir uma enquete onde o usuário poderá votar e ver o resultado dos votos.
Vamos aos conceitos. Há varias maneiras de fornecer dados para que o flex possa exibir e/ou manipular essas informações para os usuários. Se você usa PHP, pode fazer isso com zendAmf ou com AmfPHP, se usa Java, pode usar o BlazeDs. Enfim, existem diversas formas e, nesse caso, iremos usar um componente do flex que nos permite enviar e receber dados de um arquivo no servidor.
O componente é o HTTPService, que permite acessar um arquivo no servidor. Poderíamos usar RemoteObject usando zendAmf ou AmfPHP, que é mais rápido. Porém, para esse caso em que trabalhamos com um número pequeno de dados vindo do servidor, usar HTTPService resolverá nosso problema facilmente, sem comprometer o desempenho.
Atente para os seguintes detalhes, que são muito importantes.
- O atributo url deste componente seta o arquivo que será acessado pelo flex;
- O atributo result define que método será chamado quando a requisição for finalizada;
- O atributo fault define que método será chamado quando a requisição falhar.
- Para executar a requisição, é preciso usar o método send().
Imaginemos o seguinte cenário:
Você tem uma aplicação feita em flex com o nome teste.mxml. Ao compilar esse arquivo, será gerado um arquivo com o nome teste.swf. Essa aplicação precisa receber um dado do arquivo teste.php, que está no mesmo diretório do teste.swf. Para que isso ocorra, colocamos o seguinte trecho de código na nossa aplicação flex (teste.mxml):
<mx:HTTPService id="dataRequest" url="teste.php" result="RequestResult (event);" fault="FaultHandler(event);" />Trecho do código PHP:
echo "Dados enviado pelo PHP";Veja na figura abaixo o comportamento dessa transação:

Ao clicar no botão, o resultado é um alerta com a mensagem “Dado enviado pelo PHP”.
E se for necessário enviar dados do flex para o php? Bom, nesse caso iremos implementar nosso código criando um método chamado enviaDado(). Nesse método usaremos o URLVariables, que nos permitirá passar os dados do flex para o lado php. Além disso, iremos utilizar o atributo method no HTTPService, definindo que os dados serão enviados para o PHP pelo método POST. Confira o novo comportamento abaixo:

O resultado é um alerta com a mensagem “Dado enviado pelo PHP com Dado do flex”. Repare que criei o objeto URLVariables e “criei as variáveis” que serão enviadas ao servidor utilizando o comando obj.Variavel = valor;. Se tiver que enviar mais informações, basta repetir esse código, mudando apenas o nome da variável e o valor.
Depois de toda essa teoria, vamos à prática. Nosso exemplo consiste em criar um aplicativo (uma enquete) que permita aos usuários votarem em opções que serão dadas e depois conferirem o resultado da enquete. Confira o fluxo da aplicação:
Fluxo – Enquete (Flex+PHP)
- Sistema – Buscar dados do servidor;
- Sistema – Montar a estrutura da enquete;
- Usuário – Escolher uma opção;
- Sistema – Exibir Alerta pedindo confirmação do voto;
- Usuário – Confirmar a opção escolhida;
- Sistema – Enviar dados para o servidor;
- Sistema – Confirma o voto;
- Sistema – Fechar o Panel da Enquete;
- Sistema – Abrir o Panel dos resultados;
- Sistema – Busca dados sobre os resultados da enquete;
- Sistema – Anima o gráfico;
- Usuário – Clica em votar novamente;
- Sistema – Volta ao passo 3.
Fluxo Alternativo – Enquete (Flex+PHP)
1.1 Sistema – Caso não consiga buscar os dados, exibe a falha e encerra.
5.1 Usuário – Caso não confirme a escolha, o sistema confirma que não houve escolha e volta ao passo 3.
6.1 Sistema – Caso não consiga buscar os dados, exibe a falha e encerra.
Confira o gráfico que ilustra o relacionamento dos arquivos:

Explicação de cada arquivo:
- FlexEnquete.mxml = Arquivo fonte com o código flex.
- FlexEnquete.swf = Arquivo gerado a partir do FlexEnquete.mxml – esse é o arquivo que o usuário acessa e que faz a comunicação com o php.
- cfg.php = Arquivo responsável pela conexão com banco de dados.
- enquete.php = Arquivo que gera os dados da enquete.
- resultados.php = Arquivo que gera os dados com os resultados da enquete.
- voto.php = Arquivo que computa os votos.
O código está todo comentado, mas vamos a alguns detalhes relevantes:
Primeiro, atentemos para os três componentes HTTPService: cada um aponta para um arquivo php, que são os responsáveis pelas transações com o banco de dados. Todos eles (HTTPService) apontam para o evento requestFaultHandler, caso algum problema aconteça com a requisição ao PHP.
O primeiro HTTPService a ser chamado é o dataRequest, ele é responsável por trazer os dados da enquete. Se tudo ocorrer bem na requisição, será evocado o método enqueteRequestResultHandler, que tratará os retorno e irá gerar a tela da enquete.
No caso de o usuário escolher uma opção, o HTTPService que será chamado será o votoRequest, que enviará os dados e retornará a resposta para o método votoRequestResultHandler, que, por usa vez, avisará o resultado ao usuário, limpará as informações referentes à opção escolhida, fechará a tela da enquete, abrirá a tela que mostrará os resultados e chamará o método send() do HTTPService enqueteRequest, que fará uma requisição ao arquivo resultado.php. No retorno, será chamado o método enqueteRequestResultHandler, que tratará os dos dados referente ao resultado da enquente.
Outro ponto muito importante foi não deixar a enquete engessada, ou seja, a quantidade de opções de cada enquete não irá influenciar no comportamento dela. Assim, em determinado momento, poderemos definir que a enquete tenha apenas duas opções e, em outro momento, poderá ter quatro opções, e nada mudará no código.
Como fazer isso? Simples: o arquivo enquete.php informa quantas opções existem para aquela enquete, no método enqueteRequestResultHandler fazemos um for, que verifica a quantidade de opções (dados.length) e fará as iterações inserindo um HBox um Label e um RadioButton para cada opção da enquete. Desse modo, garantimos que haverá a quantidade de opções que quisermos, deixando nossa aplicação Flex mais flex 😉
Por último, destaco também o comando rb.addEventListener(MouseEvent.CLICK,rbClick). Esse comando irá criar escutas para cada RadioButton. Assim, se algum desses RadioButton forem clicados, conseguiremos saber qual e poderemos capturar informações referentes à opção clicada. O método rbClick() será chamado e receberá um argumento do tipo MouseEvent. Usando o comando evt.target.id, poderemos saber que RadioButton foi clicado. Detalhe: cada RadioButton da enquete recebe em seu id o código da opção da enquete à qual se refere. Executando o comando evt.target.value, podemos pegar o valor do RadioButton. Nesse caso, defini que seria o titulo da opção.
Em relação aos arquivos php, não irei explicá-los, uma vez que o objetivo deste artigo é o flex, mas neles não tem nada demais, apenas que dois deles geram XML e um não. Qual será o que não gera, hein?
Confira abaixo a as telas da enquete, logo após um link para vê-la em ação, um para baixar o código fonte completo (inclusive com banco de dados) e, por último, confira o código fonte totalmente comentado.

Veja o aplicativo em ação: http://www.aprendaweb.com.br/flex/FlexEnquete/
Baixe o aplicativo completo com o código fonte+PHP+BD: http://www.easy-share.com/1910024777/FlexEnqueteAprendaWeb.rar
Confira o código todo comentado
<?xml version="1.0" encoding="utf-8"?><br /><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"<br /> creationComplete="ini();" width="500" height="400" backgroundColor="#ffffff" backgroundGradientColors="#ffffff"><br /> <mx:Script><br /> <![CDATA[<br /> //Importamos os controles que serão usados na aplicação<br /> import mx.controls.RadioButton;<br /> import mx.controls.CheckBox;<br /> import mx.controls.Label;<br /> import mx.containers.HBox;<br /> import mx.controls.*;<br /><br /> //Importamos os eventos<br /> import mx.events.CloseEvent;<br /> import mx.rpc.events.FaultEvent;<br /> import mx.rpc.events.ResultEvent;<br /><br /> //Tambem usaremos o ArrayCollection para gerar a enquente<br /> import mx.collections.ArrayCollection;<br /><br /> //Array que guardará as opções<br /> public var dados:ArrayCollection;<br /><br /> //Array que guardará os dados da enquete<br /> public var enquete:ArrayCollection;<br /><br /> //Variável do tipo XMLList que será usado para gerar o gráfico de resultados<br /> [Bindable]<br /> public var resultados:XMLList;<br /><br /> //Método inicial <br /> private function ini():void{<br /> //inciamos a chamada para colher as informações sobre a enquete<br /> dataRequest.send();<br /> }<br /><br /> //Método que é chamado quando os dados da enquente são colhidos no PHP<br /> public function dataRequestResultHandler(event:ResultEvent):void {<br /> //Pegamos todos os nós 'opcao' no xml Gerado pelo PHP<br /> dados = event.result.data.opcao;<br /><br /> //Pegamos todos os nós 'enquete' no xml Gerado pelo PHP<br /> enquete = event.result.data.enquete;<br /><br /> //Colocamos a pergunta no Label com id pergunta<br /> pergunta.text = enquete[0]["titulo"];<br /><br /> //Fazemos um for para inserir todas as opções da enquete<br /> for(var n:int = 0; n < dados.length; n++){<br /> //Para cada iteração do for inserimos um HBox<br /> var h:HBox = new HBox();<br /> //Adcionamos o HBox criado no Canvas com id 'op'<br /> op.addChild(h);<br /> //Para cada iteração do for inserimos um Label<br /> var l:Label = new Label();<br /> //Colocamos o titulo da opçãoo da enquente como texto do Label<br /> l.text = dados[n]["titulo"];<br /> //Definimos o tamnho do Label<br /> l.width = 400;<br /> //Adcionamos o Label dentro do HBox que acabamos de criar <br /> h.addChild(l);<br /> //Para cada iteração do for inserimos um RadioButton<br /> var rb:RadioButton = new RadioButton();<br /> /*<br /> Aqui vai uma parte importante: adicionamos uma 'escuta' que vai<br /> ficar observando se algum dos RadioButtons foi clicado, caso algum<br /> seja clicado o método rbClick é acionado<br /> */<br /> rb.addEventListener(MouseEvent.CLICK,rbClick);<br /> /*<br /> Definimos um valor para o RadioButton neste caso o titulo da opcao<br /> da enquete.<br /> */<br /> rb.value = dados[n]["titulo"];<br /> //Definimos o id do RadioButton que será o mesmo id da opção da enquete<br /> rb.id = dados[n]["id"];<br /> //Adcionamos o RadioButton dentro do HBox Criado<br /> h.addChild(rb);<br /><br /> /*<br /> O for irá se repitir de acordo com a quantidade de opções que a enquete<br /> oferece, garantindo que haja tantos elementos quantos nescessário. Caso<br /> uma enquente só tenha duas opções o for irá se repitir 2 vezes<br /> e inserir duas opções, se for quatro opções irá se repitir 4 vezes e assim<br /> por diante, dando assim a essa enquente flex ;)<br /> */<br /> }<br /> }<br /><br /> //Método que é acionado quando um RadioButton é clicado<br /> private function rbClick(evt:MouseEvent):void {<br /> //Exibimos um alerta para o usuário confirmar seu voto. <br /> Alert.show("Você escolheu a opção: "+ evt.target.value +"\n Deseja confirmar?","Atenção",3,this, <br /> function(event:CloseEvent):void{<br /> //Se o usuário escolher sim<br /> if(event.detail == Alert.YES){<br /> //dismarcamos o RadioButton<br /> evt.target.selected = false;<br /> //criamos um objeto para passar os dados para o PHP<br /> var obj:URLVariables = new URLVariables();<br /> //passamos o id da opção<br /> obj.opCodigo = evt.target.id;<br /> //passamos o valor(titulo) da opção<br /> obj.opTitulo = evt.target.value;<br /> //enviamos os dados para o código PHP definido no HTTPService<br /> votoRequest.send(obj);<br /> }else{<br /> /*<br /> se o usuário clicar em não na confirmação do voto, dismarcamos<br /> a opção escolhida e exibimos uma mensagem avisando que o usuário<br /> ainda não realizou seu voto.<br /> */ <br /> evt.target.selected = false;<br /> resultVoto.text = "Atençao você ainda não votou! Escolha uma opção.";<br /> }<br /> });<br /> }<br /><br /> //Métado que é chamdo quando qualquer erro de chamada aos arquivos PHP falham<br /> private function requestFaultHandler(event:FaultEvent):void {<br /> Alert.show(event.fault.message);<br /> }<br /><br /> //Método que é chamado na resposta do envio do voto<br /> private function votoRequestResultHandler(event:ResultEvent):void{<br /> //Exibimos um Alerta com o texto que vem do PHP<br /> Alert.show(event.result.toString(),"Atenção!",0,null,function():void{<br /> //'Fechamos' a tela da enquete<br /> pnlEnquete.visible = false;<br /> //'Abrimos' a tela do resultado da enquete<br /> pnlResultado.visible = true;<br /><br /> /*<br /> Enviamos dados para realizar a consulta que irá gerar o resultado<br /> da enquete<br /> */<br /> var obj:URLVariables = new URLVariables();<br /> obj.enqCodigo = enquete[0]["id"];<br /> enqueteRequest.send(obj);<br /> });<br /> }<br /><br /> /*<br /> Método que é chamdo na resposta do envio dos dados para realizar a consulta <br /> que gera os dados para o gráfico <br /> */<br /> public function enqueteRequestResultHandler(event:ResultEvent):void {<br /> //colhemos os dados para o gráfico<br /> resultados = event.result.opcao;<br /> }<br /><br /> //Método para permitir o usuário votar novamente<br /> private function votarDeNovo():void{<br /> //'Abrimos' a tela da enquete<br /> pnlEnquete.visible = true;<br /> //'Fechamos' a tela do resultado da enquete<br /> pnlResultado.visible = false;<br /> }<br /> ]]><br /> </mx:Script><br /> <!--Componente para se comunicar com o arquivo enquete.php--><br /> <mx:HTTPService id="dataRequest" url="enquete.php" <br /> result="dataRequestResultHandler(event);" fault="requestFaultHandler(event);" /><br /><br /> <!--Componente para se comunicar com o arquivo resultados.php--> <br /> <mx:HTTPService id="enqueteRequest" url="resultados.php" method="POST"<br /> result="enqueteRequestResultHandler(event);" fault="requestFaultHandler(event);" resultFormat="e4x"/><br /><br /> <!--Componente para se comunicar com o arquivo voto.php--><br /> <mx:HTTPService id="votoRequest" url="voto.php"<br /> result="votoRequestResultHandler(event)" fault="requestFaultHandler(event)" method="POST"/><br /><br /> <!--Componente que gerá o efeito no gráfico dos resultados--><br /> <mx:SeriesSlide id="slideIn" duration="3000" direction="right" /><br /><br /> <!--Painel da enquete--><br /> <mx:Panel id="pnlEnquete" title="Enquete" paddingLeft="10" paddingTop="10" width="480" top="10" left="10"><br /> <!--Label que irá conter a pergunta --><br /> <mx:Label id="pergunta" fontWeight="bold" /><br /> <!--Tela que irá conter as opções--><br /> <mx:VBox id="op" /><br /> <!--Label que exibirá mensagens--><br /> <mx:Label id="resultVoto" fontWeight="bold" /><br /> </mx:Panel><br /><br /> <!--Painel do gráfico com os resultados--><br /> <mx:Panel id="pnlResultado" title="Resultado" paddingLeft="10" paddingTop="10" width="480" <br /> visible="false" top="10" left="10"><br /> <!--Definimos o dataProvider com a variavel resultados que contém os dados vindos do banco--><br /> <mx:BarChart id="Chart" height="200" color="0x323232" showDataTips="true" dataProvider="{resultados}"><br /> <!--Exibiremos as opções como legenda no eixo y--><br /> <mx:verticalAxis><br /> <mx:CategoryAxis categoryField="titulo"/><br /> </mx:verticalAxis><br /> <mx:series><br /> <!--chamaremos o efeito slideIn--><br /> <!--Os daos do eixo y será os titulos--><br /> <!--Os dados do eixo x será os votos--><br /> <mx:BarSeries id="bar" showDataEffect="{slideIn}" yField="titulo" xField="votos" displayName="Votos"/><br /> </mx:series><br /> </mx:BarChart><br /> <mx:HBox><br /> <mx:Legend dataProvider="{Chart}"/><br /> <mx:Button label="Votar novamente!" click="votarDeNovo();" /> <br /> </mx:HBox><br /> </mx:Panel><br /></mx:Application>Espero que tenham gostado! No próximo artigo, pretendo mostrar como formatar essa enquete para deixá-la com um layout muito legal. Até a próxima.







