André,
Acho que você não está entendendo muito bem a idéia dos eventos no Flex. No outro post seu, que eu e o Thiago respondemos, estava explicando bem essa parte de como o evento vai “passar” entre os seus componentes. Adicionar o listner e disparar o evento no systemManager é mais uma “gambiarra”, assim como adicionar e disparar ele no Application.application, como algumas pessoas fazem. Não fica legal fazer dessa maneira pois você está passando a responsabilidade de controlar seus eventos da aplicação toda para o systemManager, que não foi feito para isso. Para saber mais sobre ele, leia a documentação em:
http://livedocs.adobe.com/flex/3/langref/mx/managers/SystemManager.html
Para explicar melhor, vamos criar uma aplicação simples que tem duas telas: cadastro e lista de telefones.
A hierarquia vai ser assim:
- Application (Sua tela inicial, o Index)
— Cadastro de Telefones
----- Componentes do cadastro
----- etc etc etc…
— Lista de Telefones
----- Componentes da lista
----- etc etc etc…
Repare que os componentes “Cadastro de Telefones” e “Lista de Telefones” estão no mesmo nível da hierarquia, portanto somente dar o dispatch em um deles não vai fazer com que o evento chegue no outro.
Agora, vamos passar os telefones cadastrados do Cadastro, que estão em um ArrayCollection, para a Lista de telefones. Primeiro, para isso, vamos criar um evento personalizado, que vai carregar a lista de telefones com ele:
package events
{
import flash.events.Event;
import mx.collections.ArrayCollection;
public class TelefoneEvent extends Event
{
public static const ATUALIZA_LISTA_TELEFONES_EVENT:String = "atualizaListaTelefones";
public var telefones:ArrayCollection;
public function TelefoneEvent(type:String, telefones:ArrayCollection)
{
super(type);
this.telefones = telefones;
}
override public function clone():Event
{
return new TelefoneEvent(type, telefones);
}
}
}
Repare que declarei a constante com o tipo do evento dentro dele, para seguir o padrão dos outros eventos do Flex, e também a lista de telefones que esse evento vai transportar para o componente de Lista de Telefone.
Agora, no componente de Cadastro de Telefone, vamos declarar uma meta data de Event para que seja possível capturar esse evento no Application. Dessa maneira, o evento que fala que a lista precisa ser atualizada fica de responsabilidade do Cadastro de Telefones, e não no systemManager como você estava fazendo. No topo do componente de Cadastro de Telefone faça:
<mx:Metadata>
[Event(name="atualizaListaTelefones", type="events.TelefoneEvent")]
</mx:Metadata>
E crie um método em um botão que vai disparar esse evento assim:
<mx:Script>
<![CDATA[
import events.TelefoneEvent;
private var listaTelefones:ArrayCollection;
private function atualizaLista():void
{
dispatchEvent(new TelefoneEvent(TelefoneEvent.ATUALIZA_LISTA_TELEFONES_EVENT, listaTelefones));
}
]]>
</mx:Script>
<mx:Button label="Atualiza lista" click="atualizaLista()"/>
Agora no seu Application, você vai escutar o evento “atualizaListaTelefones” assim:
<local:CadastroTelefones atualizaListaTelefones="onAtualizaListaTelefones(event)"/>
Agora crie o método “onAtualizaListaTelefones” no Application que vai receber o evento e fazer o que ele quer no componente de Lista de Telefones:
<mx:Script>
<![CDATA[
import events.TelefoneEvent;
private function onAtualizaListaTelefones(event:TelefoneEvent):void
{
listaTelefones.atualiza(event.telefones);
}
]]>
</mx:Script>
<local:CadastroTelefones atualizaListaTelefones="onAtualizaListaTelefones(event)"/>
<local:ListaTelefones id="listaTelefones"/>
E na sua Lista de Telefones, você vai criar esse evento publico “atualiza” que recebe uma lista e mostra ela na tela.
Sobre a sua dúvida com o “bubbling” do event, ele faria com que o seu evento “subisse” vários níveis na hierarquia de componentes, até encontrar um listner adicionado em algum componente de nível mais alto.
Para entender melhor veja na documentação:
http://livedocs.adobe.com/flex/3/html/help.html?content=events_08.html
Espero ter esclarecido melhor suas dúvidas agora.
[]s