views:

2726

answers:

5

I'm writing an Adobe AIR application using a ViewStack for the different application states. Is there a way to make sure that each view component is created/destroyed each time it is shown/hidden?

For instance, if I have a TextInput in a view, I want it to reset to its initial state each time I change to that view, rather than having previously entered text. Or, if I have a Timer, I want it to be destroyed when I leave the view so that it doesn't keep running when I'm in an unrelated part of the application. I know that I can manually initialize/destroy everything on the show() and hide() events, but is there an easier way?

+1  A: 

AFAIK there is no built-in way to do this, so you'll have to do it manually by handling the show and hide events as you mention.

ViewStack does however have two methods "saveState" and "loadState" which could perhaps help you out with this. The history manager uses these methods to enable back/forward navigation. The docs don't seem to have any examples though.

Christophe Herreman
+1  A: 

ViewStacks can be the work of the devil when it comes to creation/deletion policies and managing state. We had all sorts of problems when we developed fiat ecoDrive and by about 3/4 of the way though we we're all very anti ViewStacks for the management of view state within our application.

However... a good bet would be to first set the creationPolicy to ContainerCreationPolicy.NONE. That way it's in your control as to when to create any of the panels in your ViewStack. Then i would think you would need to have some sort of logic so that as the ViewStack changes a panel it deletes or resets the one you were on.

Another viable alternative would be to use view states instead. Have a base state which acts as the main container and then a simple state for each of your sections. That way when you switch to a new state, the old state gets removed in reverse order to the way it was created. You do have to be disciplined with states though as they can end up getting really complex and messy when they start becoming nested. If you keep it simple it may work as you require.

James Hay
A: 

Both answers are correct -- there doesn't seem to be any built-in way to do it. I solved the problem by creating a "wrapper" component for my view component. It creates a new view component each time the view is shown. This isn't ideal, but fits my requirements nicely, and required few changes to my application structure.

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" show="init()" hide="cleanup()">
    <mx:Script>
     <![CDATA[
      private var myComponent:MyComponent;

      private function init():void
      {
       myComponent = new MyComponent();
       componentContainer.addChild(myComponent); 
      }

      private function cleanup():void
      {
       componentContainer.removeAllChildren(); 
      }
     ]]>
    </mx:Script>

    <mx:Canvas width="100%" height="100%" id="componentContainer" />
</mx:Canvas>
Rhys Causey
A: 

Build your "views" as separate Modules, and then use the ViewStack to switch between them. You could then write a function to destroy the unused module(s) (check each module against the selectedChild property) when the ViewStack's "change" event is fired.

A: 

I am using different states for my different views. On each state change i add and remove components.

This causes the add and remove events of UIComponent fire which allows me to initialize and cleanup my components each time they are added.

This is the idea...

   <mx:states>
      <mx:State name="state1">
         <mx:AddChild>
            <mx:SomeUIComponent id="myComp" add="myComp.initialize()" remove="myComp.cleanup()"/>
         </mx:AddChild>
      </mx:State>
   </mx:states>