Adobe Flex – Como colocar gráficos em repeater

abril 14, 2009 by admin · 1 Comment
Filed under: FLEX, Programação 

Estou desenvolvendo um modelo de Dashboard de Indicadores de Performace (KPI) utilizando o Adobe Flex, Asp.NET e SQL Server 2000.

Nesse Dashboard eu precisava exibir vários gráficos de acordo com o perfil de cada usuário. Por isso, construir um modelo fixo não seria possível. Então busquei maneiras de fazer isso utilizando o mx:Tile e o mx:Repeater.

Na busca encontrei apenas um exemplo de Datagrid em um Repeater, com isso foi possível construir o modelo para utilizar com Gráficos.

Primeiro é preciso entender a estrutura de DataProvider, necessária para que tudo funcione como o esperado.

Como na figura acima, o DataProvider é um ArrayCollection composto de um ArrayCollection para cada gráfico que será exibido no Repeater, cada um desse segundo ArrayCollection é composto por objetos que serão os pontos dos gráficos.

Abaixo está o código responsável pela configuração do ArrayCollection, que será o DataProvider do mx:Repeater.

<mx:Script>
        <![CDATA[
                import mx.utils.ObjectProxy;
                import mx.core.Application;
                import mx.utils.ObjectUtil;
                import mx.rpc.events.FaultEvent;
                import mx.rpc.events.ResultEvent;
                import mx.collections.ArrayCollection;

                //ArrayCollection que será o DataProvider do Repeater
                [Bindable]
                private var arDadosGraficoTotal:ArrayCollection = new ArrayCollection();

                private function load():void
                {
                        var arDadosGrafico:ArrayCollection;
                        var obDadosGrafico:ObjectProxy;

                        //Gráfico 1
                        //arDadosGrafico recebe um novo ArrayCollection
                        arDadosGrafico = new ArrayCollection();
                        //obDadosGrafico recebe um novo ObjectProxy
                        obDadosGrafico = new ObjectProxy();
                        //Cria a propriedade data1 e atribiu o 10, data1 será uma série no gráfico
                        obDadosGrafico.data1 = 10;
                        //Cria a propriedade data2 e atribiu o 5, data2 será outra série no gráfico
                        obDadosGrafico.data2 = 05;
                        //Cria a propriedade label e atribiu 'Jan', label será o eixo X do gráfico
                        obDadosGrafico.label = 'Jan';                   

//Cria a propriedade titulo e atribiu 'Vendas', titulo será o titulo do
gráfico, só existirá essa propriedade no primeiro ObjectProxy
                        obDadosGrafico.titulo = 'Vendas';      
                        //Adiciona o ObjectProxy obDadosGrafico ao ArrayCollection arDadosGrafico      
                        arDadosGrafico.addItem(obDadosGrafico);

//obDadosGrafico recebe um novo ObjectProxy e receberá os mesmas
propriedades porém com valores distintos e também é inserido ao
ArrayCollection arDadosGrafico
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 05;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 03;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 06;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

//Quando terminam os pontos do gráfico é necessário inserir o
ArrayCollection arDadosGrafico ao ArrayCollection arDadosGraficoTotal
                        arDadosGraficoTotal.addItem(arDadosGrafico);    

//Os passos anteriores devem ser feitos para cada gráfico que se deseja
exibir no Dashboard, abaixo estão identificos como Gráfico 2 e Gráfico 3
                        //Gráfico 2
                        arDadosGrafico = new ArrayCollection();
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 07;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Jan';                  
                        obDadosGrafico.titulo = 'Custos';                      
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 08;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();

                        obDadosGrafico.data1 = 05;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 04;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        arDadosGraficoTotal.addItem(arDadosGrafico);    

                        //Gráfico 3
                        arDadosGrafico = new ArrayCollection();
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 10;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Jan';                  
                        obDadosGrafico.titulo = 'Produção';                    
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 12;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 06;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 08;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        arDadosGraficoTotal.addItem(arDadosGrafico);    

//Ao terminado de incluir todos os arDadosGrafico ao
arDadosGraficoTotal, é necessário declarar arDadosGraficoTotal como
dataProvider do repeater
                        rpGrafico.dataProvider = arDadosGraficoTotal;  
                }               

        ]]>
</mx:Script>

Abaixo está o código necessário para exibir os gráficos. Inicialmente foi utilizado um Tile e dentro um Repeater. Dentro do Repeater há um Panel e dentro do Panel está o gráfico que deve ser exibido de acordo com o dataProvider.

Como demonstrado acima, o dataProvider é associado ao término da função load(). Após a associação, o Repeater começará a renderizar o primeiro gráfico, e já no título do Panel o valor atribuído será a propriedade título definida no primeiro objeto do arDadosGrafico.

Para isso é utilizada a instrução: {rpGrafico.currentItem.getItemAt(0).titulo}, ou seja, rpGrafico é o Repeater, a propriedade currentItem contém o arDadosGrafico do laço em questão e getItemAt(0) assegura que só buscará a propriedade título no primeiro objeto dentro do arDadosGrafico.

Para o gráfico, só resta associar um dataProvider a ele para que sejam exibidos os seus pontos. O dataProvider em questão será o currentItem do Repeater rpGrafico, pois como dito acima, a propriedade currentItem contém o arDadosGrafico do laço em questão.

No eixo X, horizontalAxis, é definido label como o campo fonte dos dados. No eixo Y, verticalAxis, está configurado para não começar em zero. Logo abaixo estão as duas séries, uma para o data1 (Indicador Técnico) e outra para data2 (Meta).

<mx:Tile left="10" right="10" top="10" bottom="10" direction="horizontal">
        <mx:Repeater id="rpGrafico" width="100%">
        <mx:Panel width="250" height="200" layout="absolute" id="pnGrafico" title="{rpGrafico.currentItem.getItemAt(0).titulo}">

<mx:LineChart id="grIndicador" dataTipMode="single"
showDataTips="true" dataProvider="{rpGrafico.currentItem}" width="95%"
height="95%" horizontalCenter="0" verticalCenter="0">
                        <mx:horizontalAxis>
                        <mx:CategoryAxis categoryField="label" />                              
                </mx:horizontalAxis>                                                                            
                        <mx:verticalAxis>
                                <mx:LinearAxis baseAtZero="false"/>
                        </mx:verticalAxis>                                                                              
                        <mx:series>                    
                        <mx:LineSeries form="segment" yField="data2" displayName="Meta"/>

                        <mx:LineSeries form="segment" yField="data1" displayName="Indicador Técnico"/>
                        </mx:series>
                </mx:LineChart>
        </mx:Panel>
        </mx:Repeater>
</mx:Tile>

Antes de executar o projeto e ver tudo funcionando legal, é necessário adicionar o código abaixo na segunda linha do código dentro da tag mx:Application

creationComplete=”load()”

Deixando-a assim:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="load();">

Execute o projeto, você deve obter um resultado igual a imagem abaixo.

Complementando?

Para incluir as legendas basta adicionar logo após o gráfico o código abaixo:

<mx:Legend dataProvider="{grIndicador[0]}" bottom="10" left="10" right="10" height="25"/>

Fonte: Imasters

Construindo aplicações ricas de internet com Adobe Flex 3 e ASP.NET

abril 14, 2009 by admin · 1 Comment
Filed under: .Net, FLEX, Programação 

Utilizarei o Visual Studio 2008 com o SQL Server 2005 e o banco de dados Northwind, porém os mesmos passos podem ser seguidos no Visual Studio 2005 com o SQL Server 2000.

Crie um novo projeto Web no Visual Studio, logo em seguida clique com o botão direito sobre a solução e escolha Add / New Item.

Na janela que se abrirá, selecione o Item DataSet e atribua o nome DsTerritorio.

Com o DataSet criado, clique com o botão direito dentro da janela do DataSet, escolha Add / TableAdapter, abrirá uma janela solicitando qual conexão com o banco de dados será utilizado para a construção do TableAdapter, crie a conexão com o SQL Server e salve com o nome NorthwindConn e clique em Next.

Na próxima janela selecione como o TableAdapter acessará o banco de dados, as opções possíveis são: SQL statements, criar nova Stored Procedure ou utilizar uma Stored Procedure já existente no banco de dados.

Deixe a opção Use SQL statements marcada e clique em Next.

A próxima janela é onde se insere o código SQL para o retorno dos dados, porém você pode utilizar o Query Builder, que é a ferramenta visual para construção de instruções SQL, portanto clique no botão Query Builder.

Após clicar no botão Query Builder, aparecerão duas janelas, a janela do próprio Query Builder e a janela de Add Table, a segunda janela já com as tabelas existentes no banco de dados.

Procure e selecione a tabela Region, em seguida, clique em Add. A tabela Region aparecerá no Query Builder.

Clique em Close, em seguida, selecione as duas colunas da tabela Region (RegionID e RegionDescription). Agora clique em Execute Query.

Se o resultado do Execute Query for igual à figura acima, clique em Ok. A próxima janela solicitará nomes para os métodos de Fill e Return que por padrão são Fill e GetData respectivamente.

Para a tabela Region, deixe os nomes sugeridos e clique em Next. A próxima janela exibirá o sumário da criação do TableAdapter. Clique em Finish.

Agora já é possível visualizar o TableAdapter dentro do DataSet dsTerritorio.

Ainda dentro do DataSet dsTerritorio, crie outro TableAdapter. Novamente, clique com o botão direito dentro do DataSet, escolha Add / TableAdapter, escolha a conexão com a base de dados, também escolha Use SQL statements.

Na janela do Query Builder, adicione a tabela Territories, selecione todas as colunas. Na linha RegionID, insira o parâmetro @RegionID na coluna Filter. O parâmetro será responsável por aplicar o filtro de qual região o SQL retornará os territórios.

Na janela de definições dos métodos, acrescente a expressão ByRegionID, após Fill e GetData. Dessa maneira apenas pelo nome do método é possível saber que um parâmetro chamado RegionID é esperado.

Agora que concluiu a criação do DataSet dsTerritorio, crie o DataSet dsVendedor, e dentro dele crie um TableAdapter com o SQL abaixo.

SELECT  EmployeeTerritories.EmployeeID,
        Employees.FirstName + ' ' + Employees.LastName AS FullName,
        EmployeeTerritories.TerritoryID
FROM Employees INNER JOIN EmployeeTerritories
        ON Employees.EmployeeID = EmployeeTerritories.EmployeeID
WHERE (EmployeeTerritories.TerritoryID = @TerritoryID)

Acrescente ByTerritoryID na definição dos métodos Fill e GetData.

Após clicar em Finish, o TableAdapter criado estará com os nomes DataTable1 e DataTable1TableAdapter, altere-os para Employee e EmployeeTableAdapter.

Crie um novo DataSet chamado dsCliente, e também crie um novo TableAdapter com o código abaixo.

SELECT  Customers.CustomerID, Customers.CompanyName, CustomerEmployee.EmployeeID
FROM (SELECT CustomerID, EmployeeID
        FROM Orders
        GROUP BY CustomerID, EmployeeID) AS CustomerEmployee INNER JOIN
        Customers ON CustomerEmployee.CustomerID = Customers.CustomerID
WHERE (CustomerEmployee.EmployeeID = @EmployeeID)

Para os nomes dos métodos Fill e GetDate, não esqueça de adicionar ByEmployeeID em ambos.

Como no TableAdapter de vendedores, os nomes deste TableAdapter também não estão corretos, altere-os para Customers e CustomersTableAdapter respectivamente.

Para concluir a construção dos DataSets, crie mais um chamado dsPedido e também crie um novo TableAdapter com o código abaixo.

SELECT OrderID, CustomerIR, EmployeeID, OrderDate, ShippedDate,
        ShipName, ShipAddress, ShipCity, Shipcountry
FROM Orders
WHERE (CustormerID = @CustomerID) AND
        (EmployeeID = @EmployeeID)

Acrescente ByCustomerIDEmployeeID aos métodos Fill e GetData e clique em Finalizar.

Agora crie o último TableAdapter chamado OrderDetails conforme a figura abaixo.

Após a criação de todos os DataSets (Território, Vendedor, Cliente e Pedido) o projeto deve estar conforme a figura abaixo.

Copie os seguintes arquivos do diretório de instalação do WebOrb (por padrão em c:\inetpub\wwwroot\weborb30) para o diretório do projeto .NET.

/weborb.config
/bin/weborb.dll
/WEB-INF

Adicione o código XML abaixo ao web.config do projeto .NET.

<configuration>
 <system.web>
   <httpHandlers>
     <add verb="*" path="weborb.aspx" type="Weborb.ORBHttpHandler"/>
     <add verb="*" path="codegen.aspx" type= "Weborb.Management.CodeGen.CodegeneratorHttpHandler"/>
   </httpHandlers>
 </system.web>
</configuration>

É preciso referenciar o weborb.dll ao projeto, para isso no Solution Explorer do Visual Studio, clique duas vezes sobre a opção My Project, em seguida clique em References e depois em Add / References?

Clique na aba Browse, localize o diretório Bin do projeto, selecione o arquivo weborb.dll e clique em OK, salve o projeto e feche a janela My Project.

Clique com o botão direito sobre a solução e escolha Add / New Item, porém escolha Class e dê o nome de csFlex.vb.

Nesta classe serão criados os métodos de chamada e retorno dos DataSets e TableAdapters criados anteriormente, através desses métodos é que a comunicação entre o .NET e o Flex ocorrerá.

Insira o código abaixo ao arquivo csFlex.vb

Imports Weborb.Service

Public Class csFlex

    Public Function getRegion() As DataTable
        Return New dsTerritorioTableAdapters.RegionTableAdapter().GetData()
    End Function

    Public Function getTerritories(ByVal RegionID As String) As DataTable
        Return New dsTerritorioTableAdapters.TerritoriesTableAdapter().GetDataByRegionID(RegionID)
    End Function

    Public Function getEmployee(ByVal TerritoryID As String) As DataTable
        Return New dsVendedorTableAdapters.EmployeeTableAdapter().GetDataByTerritoryID(TerritoryID
    End Function

    Public Function getCustomers(ByVal EmployeeID As String) As DataTable
        Return New dsClienteTableAdapters.CustomersTableAdapter().GetDataByEmployeeID(EmployeeID)
    End Function

    Public Function getOrders(ByVal CustomerID As String, ByVal EmployeeID As String) As DataTable
        Return New dsPedidoTableAdapters.OrdersTableAdapter().GetDataByCustomerIDEmployeeID(CustomerID, EmployeeID)
    End Function

    Public Function getOrderDetails(ByVal OrderID As String) As DataTable
        Return New dsPedidoTableAdapters.OrderDetailsTableAdapter().GetDataByOrderID(OrderID)
    End Function

End Class

Salve e feche o arquivo csFlex, agora compile o projeto. Caso o Visual Studio sinalize algum erro, volte e execute os passos novamente.

Antes de criar a interface no Adobe Flex, crie a aplicação Web no Internet Information Services (IIS) com o nome do projeto, verifique se ao acessar o endereço através do navegador uma página em branco é exibida.

Agora já com a aplicação web configurada no IIS, abra o Adobe Flex Builder 3, adicione um novo projeto (File / New / Flex Project).

Agora defina o nome do Projeto, se a opção Use default location estiver marcada, desmarque-a e localize o endereço do projeto .NET e dentro da pasta do projeto crie uma nova pasta chamada FlexSrc. O Project location do Flex deve ficar como a figura abaixo. A opção de Application type deixe marcado Web Application, e em Server technology selecione ASP.NET. Clique em Next.

Na próxima janela, na opção Server selecione Use Internet Information Services (IIS), em Web application root informe o diretório raiz da aplicação web definida no IIS e no campo Web application URL informe o endereço da aplicação no IIS. Após clicar no botão Validate Configuration, na parte superior da janela o Flex Builder deve ser informar: “The web application root and URL are valid”, caso apareça outra mensagem, os endereços informados não estão corretos, corrija antes de prosseguir.

Na mesma janela, um pouco abaixo está definida a pasta bin-debug como local a serem salvos os arquivos Flex compilados, deixe o nome que o Builder sugeriu e clique Next.

Na última janela de configuração do projeto Flex, é possível definir qual a pasta onde o Flex Builder salvará os arquivos fontes, bem como qual o nome do primeiro arquivo do projeto a ser criado.

Deixe os campos preenchidos como o Builder sugeriu e clique em Finish. Após alguns segundos o Adobe Flex Builder 3 exibirá o arquivo ArtigoFlex.mxml pronto para o início da construção da interface da aplicação.

Porém antes começar a codificar é necessário incluir um argumento de compilação ao projeto, pois sem esse argumento o Flex não conseguirá acessar os métodos construídos na classe csFlex. Para incluir o argumento, clique com o botão direito sobre o nome do projeto no Flex Navigator e em seguida clique em Properties. Com a janela de propriedades aberta, clique sobre a opção Flex Compiler, e insira o argumento após o argumento ?locale en_US

-services c:\Inetpub\wwwroot\weborb30\web-inf\flex\services-config.xml

Após inserir o argumento services, clique em OK.

Agora com o projeto corretamente configurado e pronto para comunicar com o .NET é possível iniciar a construção da interface, para tanto crie um painel, entre as tags , com o título Painel de Vendas, esse painel terá um tamanho ajustável conforme as dimensões do navegador do cliente, para isso configure as propriedades left, right, top e bottom, todos com o valor 10.

<mx:Panel layout="absolute" left="10" right="10" top="10" bottom="10" title="Painel de Vendas">
</mx:Panel>

É possível verificar como o projeto está ficando, bastar clicar no Play.

Dentro do painel, crie um canvas na cor cinza.

<mx:Canvas height="42" left="0" top="0" right="0" backgroundColor="#F3F3F3" borderStyle="none" borderThickness="1" borderColor="#C2BEBE">

</mx:Canvas>

Dentro do canvas coloque os labels e comboboxs que serão utilizados para selecionar região, território, vendedor e cliente, coloque também dentro do canvas o botão consultar.

<mx:Label y="12" text="Região" horizontalCenter="-348"/>
<mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" horizontalCenter="-274"></mx:ComboBox>
<mx:Label y="12" text="Território" horizontalCenter="-194"/>
<mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" horizontalCenter="-114"></mx:ComboBox>
<mx:Label y="12" text="Vendedor" horizontalCenter="-32"/>
<mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" horizontalCenter="49"></mx:ComboBox>
<mx:Label y="12" text="Cliente" horizontalCenter="124"/>
<mx:ComboBox y="10" id="cbCustomer" labelField="CompanyName" width="89" horizontalCenter="198"></mx:ComboBox>
<mx:Button y="10" label="Consultar" width="119" horizontalCenter="310" id="btConsultar"/>

A propriedade horizontalCenter define qual a distância em pixel que um objeto está do centro da página, valores negativos representam objetos a esquerda do centro da tela e valores positivos representam objetos a direita, os valores definidos garantem que os objetos estarão sempre centralizados.

labelField é a propriedade que define qual o campo que será exibido como label do combobox. O Adobe Flex trabalha de maneira diferente do .NET quando o assunto é combobox ou dropdownlist, pois no .NET é possível definir apenas dois valores ao dropdownlist, o datatextfield e o datavalueFfeld, já no Adobe Flex só se define qual será o valor de exibição do combobox, labelField, pois cada linha de opção do combobox é um objeto com propriedades. Essas propriedades são as colunas que retornaram do banco de dados, logo você não tem acesso a somente duas colunas como dropdownlist, você tem acesso a todas as colunas que retornaram do banco de dados.

A propriedade Y define qual a distância que o objeto tem do topo do componente ao qual ele está pertencendo, neste caso, y=”12″ diz ao Flex que o label está a 12 pixel do topo do canvas.

Após o canvas inclua um datagrid onde serão exibidos os pedidos resultantes da consulta ao banco de dados.

<mx:DataGrid id="dgPedido" right="10" left="10" top="55" bottom="10">
<mx:columns>
        <mx:DataGridColumn headerText="Detalhes" width="85"/>
        <mx:DataGridColumn headerText="Data Pedido" dataField="OrderDate"/>
        <mx:DataGridColumn headerText="Data Entrega" dataField="ShippedDate"/>
        <mx:DataGridColumn headerText="Entregue para" dataField="ShipName"/>
        <mx:DataGridColumn headerText="Endereço" dataField="ShipAdress"/>
        <mx:DataGridColumn headerText="Cidade" dataField="ShipCity"/>
        <mx:DataGridColumn headerText="País" dataField="ShipCountry"/>
</mx:columns>
</mx:DataGrid>

Para fazer a comunicação entre a interface Flex e a aplicação server-side .NET utilize o componente RemoteObject do Adobe Flex 3.

<mx:RemoteObject id="roNet" destination="GenericDestination"
        source="ArtigoFlex.csFlex" showBusyCursor="true"
        fault="faultHandler(event)" >

        <mx:method name="getRegion" result="gotRegion(event)" />
        <mx:method name="getTerritories" result="gotTerritories(event)" />
        <mx:method name="getEmployee" result="gotEmployee(event)" />
        <mx:method name="getCustomers" result="gotCustomers(event)" />
        <mx:method name="getOrders" result="gotOrders(event)" />
        <mx:method name="getOrderDetails" result="gotOrderDetails(event)" />

</mx:RemoteObject>

A propriedade destination deve sempre ser “GenericDestination” para a comunicação através do weborb, a propriedade source deve ser preenchida com o nome do projeto .NET e a classe que será acessada, então neste caso será “ArtigoFlex.csFlex”.

A propriedade showBusyCursor seta se será exibido ou não o relógio como cursor do mouse enquanto alguma requisição ao .NET estiver sendo feita. E finalmente, fault define qual função será disparada caso algum erro ocorra durante alguma requisição do .NET.

Os métodos (

A propriedade result define qual função será disparada após o retorno da requisição ao .NET.

É necessário agora construir as funções, faultHandler, gotRegion, gotTerritories, gotEmployee, gotCustomers, gotOrders e gotOrderDetails. As funções são escritas na linguagem Action Script 3.0

<mx:Script>
        <![CDATA[
                import mx.rpc.events.ResultEvent;
                import mx.controls.Alert;
                import mx.rpc.events.FaultEvent;
        ]]>
</mx:Script>

Nesta parte do código além do bloco das tags de inicio e fim de script, também estão declaradas as importações das bibliotecas ResultEvent, Alert e FaultEvent que serão utilizadas logo mais.

Agora crie a função faultHandler

private function faultHandler(event:FaultEvent):void
{
        Alert.show(event.fault.faultString, "Erro");
}

A função faultHandler recebe um parâmetro do tipo FaultEvent que será exibido para o usuário através do Alert.show quando algum erro ocorrer durante a requisição ao .NET.

Agora crie os métodos de preenchimento dos valores do combobox região.

private function bindRegion():void
{
        roNet.getRegion();
}

private function gotRegion(event:ResultEvent):void
{
        cbRegion.dataProvider = event.result;
        cbRegion.selectedIndex = 0;
        bindTerritories();
}

No código acima foram criadas duas funções, bindRegion e gotRegion. A função bindRegion chama o método getRegion do remote object roNet.

Após o retorno da requisição ao método roNet.getRegion, a função gotRegion é disparada recebendo um parâmetro do tipo ResultEvent que contém o retorno do método getRegion, o retorno é associado como dataProvider do combobox cbRegion, em seguida é selecionado o índice zero dos dados retornados. Após a seleção do índice, a função bindTerritories() é disparada.

private function bindTerritories():void
{
        roNet.getTerritories(cbRegion.selectedItem.RegionID);
}

private function gotTerritories(event:ResultEvent):void
{
        cbTerritory.dataProvider = event.result;
        cbTerritory.selectedIndex = 0;
        bindEmployee();
}

Assim como a função bindRegion, bindTerritories chama um método do remote object roNet, porém agora o método chamado é o getTerritories, esse método espera como parâmetro o código da região, por isso o parâmetro informado é o cbRegion.selectedItem.RegionID. RegionID é uma propriedade que o dataProvider do cbRegion passou a ter após a atribuição do event.result. Abaixo estão as demais funções para a preparação dos comboboxs.

private function bindEmployee():void
{
        roNet.getEmployee(cbTerritory.selectedItem.TerritoryID);
}

private function gotEmployee(event:ResultEvent):void
{
        cbEmployee.dataProvider = event.result;
        cbEmployee.selectedIndex = 0;
        bindCustomers();
}       

private function bindCustomers():void
{
        roNet.getCustomers(cbEmployee.selectedItem.EmployeeID);
}

private function gotCustomers(event:ResultEvent):void
{
        cbCustomer.dataProvider = event.result;
        cbCustomer.selectedIndex = 0;
}

Para que quando o usuário acesse a aplicação os comboboxs já sejam preenchidos é necessário definir a propriedade creationComplete na tag mx:Application.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="bindRegion()">

Com essa propriedade definida, depois de criada a aplicação, a função bindRegion será disparada iniciando assim a população de todos os comboboxs, pois eles estão aninhados.

Também é preciso configurar os comboboxs para que depois de alterada a seleção de um dos filtros, os outros sejam alterados também, para isso será utilizada a propriedade change.

<mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" change="bindTerritories()" horizontalCenter="-274"></mx:ComboBox>
<mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" change="bindEmployee()" horizontalCenter="-114"></mx:ComboBox>
<mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" change="bindCustomers()" horizontalCenter="49"></mx:ComboBox>

Agora faça a população da datagrid,

private function bindOrders():void
{
        roNet.getOrders(cbCustomer.selectedItem.CustomerID,cbEmployee.selectedItem.EmployeeID);
}

private function gotOrders(event:ResultEvent):void
{
        dgPedido.dataProvider = event.result;
}

Para que a função bindOrders seja disparada ao clicar o botão Consultar, defina a propriedade click do botão btConsultar.

<mx:Button y="10" label="Consultar" width="119" click="bindOrders()" horizontalCenter="310" id="btConsultar"/>

Para finalizar o projeto, crie a estrutura para exibir os detalhes dos pedidos. Para isso crie uma TitleWindow, em File / New / MXML Component, defina o nome de orderDetails, baseado em TitleWindow

Utilize o código abaixo para a TitleWindow orderDetails.

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="730" height="420" title="Detalhes do Pedido" showCloseButton="true" close="{PopUpManager.removePopUp(this)}">
<mx:Script>
        <![CDATA[
                import mx.managers.PopUpManager;
                import mx.events.CloseEvent;
        ]]>
</mx:Script>
<mx:DataGrid left="10" right="10" top="10" bottom="10" id="dgOrderDetails">
<mx:columns>
        <mx:DataGridColumn headerText="Cód." dataField="ProductID"/>
        <mx:DataGridColumn headerText="Produto" dataField="ProductName"/>
        <mx:DataGridColumn headerText="Preço Un." dataField="UnitPrice"/>
        <mx:DataGridColumn headerText="Qtde" dataField="Quantity"/>
        <mx:DataGridColumn headerText="Desconto" dataField="Discount"/>
        <mx:DataGridColumn headerText="Total" dataField="Total"/>
</mx:columns>
</mx:DataGrid>  
</mx:TitleWindow>

Crie as funções para a população da TitleWindow orderDetails dentro do script do arquivo ArtigoFlex.mxml

import mx.managers.PopUpManager;

public function bindOrderDetails():void
{
        roNet.getOrderDetails(dgPedido.selectedItem.OrderID);
}

private function gotOrderDetails(event:ResultEvent):void
{
        var popUp:orderDetails = orderDetails(PopUpManager.createPopUp(this, orderDetails, true));
        PopUpManager.centerPopUp(popUp);
        popUp.dgOrderDetails.dataProvider = event.result;                                              
}

Altere a primeira coluna da datagrid dgPedido para o código abaixo para inserir o botão para exibir os detalhes do pedido.

<mx:DataGridColumn headerText="Detalhes" width="85">
<mx:itemRenderer>
<mx:Component>                                          
        <mx:HBox width="100%" height="100%" horizontalAlign="center">
                <mx:Button y="10" width="80" label="Detalhes" click="outerDocument.bindOrderDetails()" id="btDetalhes"/>
        </mx:HBox>                      
</mx:Component>
</mx:itemRenderer>                              
</mx:DataGridColumn>

Salve o projeto e execute, o resultado deve ser como o das figuras abaixo.

Baixe o código fonte completo.

Divirta-se.

Publicado originalmente em http://www.igormusardo.com.br

Fonte: Imasters

SEO Powered by Platinum SEO from Techblissonline