Flex e PureMVC – Deferred Instantiation
Durante um trabalho recente utilizando Flex e o framework PureMVC, enfrentei um problema para registrar alguns mediators com as referências de componentes visuais que ainda não haviam sido criados durante o startup da aplicação.
Usando como exemplo um ViewStack ou um TabNavigator, onde embora vários filhos estejam definidos dentro do MXML, apenas o filho que estará visível inicialmente será instanciado, uma vez que você tenha setado o creationPolicy=”auto”
(ou não tenha setado nada, já que esse é o valor default da propriedade). Os demais filhos, portanto, serão instanciados somente à partir do momento que você navegar por eles.
Do ponto de vista da performance, isso seria excelente, já que o usuário poderia não navegar por todos os filhos e você estaria então poupando tempo e memória.
Infelizmente, esse é um cenário simplista de uma aplicação e pode não ser suficiente para atender suas necessidades, já que no momento do startup nós não temos as referências de todos os componentes visuais, uma vez que eles ainda não foram criados.
Embora nós possamos registrar todos mediators e mais tarde dar as referências dos seus respectivos componentes visuais, ou mesmo setar creationPolicy=”all” (que diminuiria a performance e aumentaria o consumo de memória), isso vai de encontro com o comportamento de uma poderosa característica do Flex, chamada deferred instantiation.
Seu uso traz benefícios de performance durante a inicialização da aplicação, se comparado com os exemplos anteriores, mas traz também um pouco mais de complicação para seu código. Dessa forma, é estritamente recomendado que todo desenvolvedor Flex conheça muito bem seu comportamento, não importando se está utilizando ou não o PureMVC.
Em suma, ao invés de registrarmos todos os mediators no ApplicationMediator.as, nós o fazemos parcialmente, após a criação dos componentes visuais, com o auxílio de eventos. Ao navegar num ViewStack, por exemplo, um evento deve ser disparado informando que o filho (componente visual) foi criado, e tal evento deve ser então escutado no mediator correspondente do ViewStack. O método que será disparado por esse evento deverá registrar o mediator do filho (já que agora possuimos uma referência para o view), caso ele ainda não o esteja.
Abaixo podemos observar um código que descreve o comportamento descrito acima:
ApplicationMediator.as
-
override public function onRegister():void
-
{
-
facade.registerMediator(new MainDisplayMediator(app.mainDisplay));
-
app.addEventListener( Slacker.SHOW_GALLERY, onShowGallery );
-
app.addEventListener( Slacker.SHOW_EDITOR, onShowEditor );
-
app.addEventListener( Slacker.SHOW_PROFILE, onShowProfile );
-
}
MainDisplay.mxml
-
<mx:ViewStack id="myStack" selectedIndex="{currentViewSelector}" creationPolicy="auto" width="100%" height="100%">
-
<view:SplashView />
-
<view:GalleryView creationComplete="sendEvent(GALLERY_CREATED)"/>
-
<view:EditorView creationComplete="sendEvent(EDITOR_CREATED)"/>
-
<view:ProfileView creationComplete="sendEvent(PROFILE_CREATED)"/>
-
</mx:ViewStack>
MainDisplayMediator.as
-
override public function onRegister():void
-
{
-
mainDisplay.addEventListener( MainDisplay.GALLERY_CREATED, onGalleryCreated );
-
mainDisplay.addEventListener( MainDisplay.EDITOR_CREATED, onEditorCreated );
-
mainDisplay.addEventListener( MainDisplay.PROFILE_CREATED, onProfileCreated );
-
}
-
protected function onGalleryCreated( event:Event ):void
-
{
-
checkForMediator( MainDisplay.GALLERY, mainDisplay.activeView );
-
}
-
-
protected function checkForMediator( childSelector:Number, child:Object ):void
-
{
-
switch (childSelector)
-
{
-
case MainDisplay.PROFILE:
-
if ( ! facade.hasMediator( ProfileViewMediator.NAME ) )
-
facade.registerMediator(new ProfileViewMediator( child ));
-
break;
-
case MainDisplay.GALLERY:
-
if ( ! facade.hasMediator( GalleryViewMediator.NAME ) )
-
facade.registerMediator(new GalleryViewMediator( child ));
-
break;
-
case MainDisplay.EDITOR:
-
if ( ! facade.hasMediator( EditorViewMediator.NAME ) )
-
facade.registerMediator(new EditorViewMediator( child ));
-
break;
-
}
-
}
Referências:
http://puremvc.org/pages/demos/AS3/Demo_AS3_Flex_Slacker/srcview/index.html
Um comentário para “Flex e PureMVC – Deferred Instantiation”
Já tinha acontecido isso comigo tambem, logo quando comecei ver PureMVC. Da um pouco de trabalho, ficar registrando os mediators dos componentes filhos dentro do mediator pai. Mas acho que é uma boa solução =). abraço

