Passar variável - Accordion

5 views
Skip to first unread message

Airton Toyansk

unread,
Nov 7, 2009, 2:37:31 PM11/7/09
to fle...@googlegroups.com
Pessoal,
 
Tenho a seguinte estrutura: um arquivo com um Accordion, que, para cada aba dele, existe um componente.

<mx:Accordion

id="tabP">

<local:tlEntrada/>

<local:tlModulos/>

</mx:Accordion>
No primeiro componente (tlEntrada) tenho um datagrid id="dg" com alguns registros, e um botão de editar, que, ao ser clicado, leva o usuário à segunda aba: parentDocument.tabP.selectedIndex = 1;
 
No segundo componente (tlModulos), tenho um TextInput que quero que exiba o id do registro no datagrid que o usuário clicou para editar.
Como posso recuperar esta variável no arquivo tlModulos?
 
Seria algo como <mx:TextInput id="editando" text="{tlEntrada.dg.selectedItem.id}"/>, mas isso não funciona...
 
Agradeço as respostas!
 
Airton Toyansk
 
 

Vicente Maciel Junior

unread,
Nov 7, 2009, 4:46:52 PM11/7/09
to fle...@googlegroups.com
Não é interessante que dentro de um componente vc tenha referências "hard-coded" à outros componentes. Isso faz com que seu componente perca a capacidade de reutilização, etc.

No seu lugar, ou eu criaria eventos personalizados, que transportariam valores em sua ocorrência, ou então, em casos mais simples criaria "bindings" para fazer com que um componente tivesse acesso à dados de um outro componente. De repente, até as duas soluções juntas formam o conjunto de soluções ideais para o seu caso.

Vou tentar colocar aqui um mini tutorial de uma das maneiras de vc resolver isso...

Dentro do seu componente "tlEntrada", vc poderia disparar um evento que notificasse o clique do botão editar. Para fazer isso de uma forma bem simples:

1 - No código do clique do botão, adicione (ou altere para):
dispatchEvent(new Event("edit"));

2 - Adicione ao componente "tlEntrada" a Metatag que inclusive adicionará o evento ao code-hinting do Flex Builder em relação a esse componente:
<mx:Metadata>
   [Event(name="editar",type="flash.events.Event")]
</mx:Metadata>

3 - Agora, na ocorrência do evento, você pode fora do componente, especificar o que vc quer que aconteça quando o mesmo for disparado:

<local:tlEntrada edit="tabP.selectedIndex = 1"/>

ou

<local:tlEntrada edit="tlEntradaEditHandler()"/>
e na seção <mx:Script>:
private function tlEntradaEditHandler():void
{
   tabP.selectedIndex = 1;
}

Pronto! O componente "tlEntrada" não precisa mais fazer nenhuma referência direta a nenhum outro componente, mantendo então seu funcionamento totalmente independente, ganhando assim capacidade de reutilização.

Uma questão resolvida, mas falta o mais importante... fazer com que o componente "tlModulos" saiba qual foi o "selectedIndex" do DG em "tlEntrada".

Como eu disse, tem várias formas de se fazer isso. Uma delas, é a seguinte:

1 - No componente "tlModulos" vamos criar uma variável "bindable" que vai receber o valor do "selectedIndex" do DG do componente "tlEntrada". Vamos definir essa variável através de um Setter para que possamos acionar algum código quando o valor atribuido para a mesma mudar. Para isso, dentro do componente "tlModulo", na seção <mx:Script> adicione:

private var itemToEditIndex:int;
[Bindable]
public function set itemToEditIndex(value:int):void
{
   _itemToEditIndex = value;
   //talvez vc sinta a necessidade de chamar uma funcao aqui para
   //apresentar na interface os dados relacionados ao novo
   //indice. algo como mostrarDadosDoRegistroNosCampos()...
}
public function get itemToEditIndex():int
{
   return _itemToEditIndex;
}

2 - Fazer uma mudança na etapa 3 anterior para mudar o valor da nova propriedade "itemToEditIndex" que criamos para o componente "tlModulos", para que o mesmo contenha o valor do indice selecionado no DG dentro do componente "tlEntrada":

<local:tlEntrada id="tlEntrada" edit="tabP.selectedIndex = 1; tlModulos.itemToEditIndex = tlEntrada.dg.selectedIndex"/>

ou

<local:tlEntrada edit="tlEntradaEditHandler()"/>
e na seção <mx:Script>:
private function tlEntradaEditHandler():void
{
   tabP.selectedIndex = 1;
   tlModulos.itemToEditIndex = tlEntrada.dg.selectedIndex;
}

3 - Repare que esse codigo acima faz referência aos componentes através de seus respectivos IDs, que no caso eu defini usando seus proprios nomes. ou seja:

<local:tlEntrada id="tlEntrada"/>

<local:tlModulos id="tlModulos"/>


Eu mesmo não considero essa solução acima como a ideal. Eu a faria criando um evento personalizado para o componente "tlEntrada" e trabalharia com o tráfego de dados dentro do evento, criando uma classe "DTO" para representar o dado selecionado/editado. Mas a solução para descrever aqui ficaria um pouco mais complexa. 

Mas essa forma que descrevi é uma forma que encontrei de mostrar mais didaticamente como usar o benefício dos:

- Eventos disparados por componentes personalizados
- Binding
- getters / setters

Boa sorte!


Vicente Maciel Junior
========================================
RiaBrazil - Senior Rich App Developer
Independent Web Developer & Consultant
Adobe Certified Expert on ColdFusion and Flex with AIR
---------------------------------------------------------------------------------
+55 71 8120-0035 MSN: maci...@gmail.com / Twitter: macieljr
---------------------------------------------------------------------------------
http://www.riabrazil.com.br - http://teclandoalto.blogspot.com
Grupo de usuarios Oficial Adobe RIA-BA: http://bit.ly/ria-ba
Google Profile: http://www.google.com/profiles/macieljr
========================================


2009/11/7 Airton Toyansk <atoy...@gmail.com>

Airton Toyansk

unread,
Nov 7, 2009, 9:22:19 PM11/7/09
to fle...@googlegroups.com
Vicente,
 
Muito obrigado pelo tutorial! Vou testar aqui...
De qualquer forma, gostaria de estudar sobre DTO e eventos personalizados e, quem sabe, chegar na "solução ideal" para o problema.
Se não for pedir demais, se vc tiver algum link que possa me ajudar...
Obrigado,
 
Airton Toyansk
 

 
2009/11/7 Vicente Maciel Junior <maci...@gmail.com>

Airton Toyansk

unread,
Nov 8, 2009, 8:09:14 AM11/8/09
to fle...@googlegroups.com
Vicente,
 
O primeiro item, que faz com que o componente tlEntrada se torne independente, deu certo.
 
Já o segundo, que enviaria o selectedIndex do DG para o componente tlModulos, não está funcionando...
Meu código está assim:
 

private

function printEdit():void

{

edit_txt.text = _itemToEditIndex.toString();

}

[

Bindable]

public function set itemToEditIndex(value:int):void

{

_itemToEditIndex = value;

printEdit();

}

public function get itemToEditIndex():int

{

return _itemToEditIndex;

}

private var _itemToEditIndex:int;

 

Não está dando erro, mas também não exibe no textInput o id do item selecionado no DG do componente tlEntrada...
Alguma idéia do que pode ser?
 
Obrigado!
 
Airton Toyansk



2009/11/8 Airton Toyansk <atoy...@gmail.com>

Airton Toyansk

unread,
Nov 8, 2009, 9:22:02 AM11/8/09
to fle...@googlegroups.com
Opa, um pequeno detalhe:
 
Alterei por exibir o valor através de um DataBinding:
 
<mx:TextInput id="edit_txt" text="{_itemToEditIndex}"/>
 
E retirei a função printEdit()... E funcionou =D

Eduardo Kraus

unread,
Nov 9, 2009, 1:57:20 AM11/9/09
to fle...@googlegroups.com

Há também como resolver isso usando o createPolyce="all" no Accordion

Eduardo Kraus

Desenvolvedor
eduard...@gmail.com
blog.mxml.com.br
www.twitter.com/EduardoKraus



2009/11/7 Airton Toyansk <atoy...@gmail.com>
Reply all
Reply to author
Forward
0 new messages