I have an app w/ a login screen. When the user hits "enter", the state changes to "login" & a child component is triggered to load (though the child stays invisible at the moment). The child contains many functions that the user needs upon logging in (ie their screenname & settings are retrieved from a database). The following is included in 'Parent':
<local:comp id="localComp" includeIn="login" includeInLayout="false" visible="false"/>
<mx:Button label="login" click="currentState='login'"/>
<mx:Button label="logout" click="currentState='Default'"/>
My problem is when a user logs out (state changes to 'Default') & then logs back in (state changes back to 'login') the child doesn't get "triggered" again & the functions w/in the child don't reload. Is there a way to force my child to refresh?
Note: While it 开发者_开发问答would be easier to just move the child's functions to the parent it is complex...I moved these functions to the child to make it easier to follow
UPDATE: I even tried adding an "exitState" to my state:
<s:State name="login" exitState="removeElement(localComp)" />
This doesn't work either, as I get an error: "RangeError: Index 0 is out of range."
UPDATE: Even though you are allowed to call a child's function from a parent, my problem is that the child needs to be "created" in order to not show errors. It makes no sense to me why the flex team would make something like removing & adding children so complicated.
First, I think you don't have to set both includeIn and visible+includeInLayout properties in your custom component. When using includeIn, the framework will automatically remove your component from the display list when it's in another state than "login".
To answer your question, I would use rather addedToStage (inside your custom component) event or currentStateChanged (in the parent component) events. These events should be triggered when the state changes to login
Your child doesn't get "triggered" again because it's the same child each time you switch states. Flex is just toggling it's visibility--it's still the exact same object. If you want to do specific things when it's addedToStage, you'll want to remove/add that child to the stage when the state changes instead of just toggling its visibility.
A useful way of doing this is with Flex 3's <mx:AddChild/>
Example:
<mx:states>
<mx:State name="login">
<mx:AddChild position="firstChild">
<local:comp id="localComp"/>
</mx:AddChild>
</mx:State>
</mx:states>
If I'm reading this correctly, localComp
is a non-visual component that handles the heavy lifting of logging you into some service, correct?
Does enterState
fire on localComp
? You could call init
from there. Or, if init()
is the initialize handler for your component, have it do any necessary plumbing work that has to stick around, and move the actual at-time-of-login code to a separate function.
Of course, this is not actually how I would do this anyway. Putting logic into a component, which has all the infrastructure to allow it to be part of a display object graph, and then not displaying it, is wasteful. Instead, have your "component" inherit from Object or something, then simply declare an instance of it inside a script block. Then you can just call its logic directly from login
's click
handler. Just use states to update the state of the UI... which is really what they're meant for.
<mx:Button label="login" click="login_clickHandler(event)"/>
<mx:Button label="logout" click="currentState='Default'"/>
<fx:Script>
<![CDATA[
protected var localComp:MyComponent = new MyComponent();
protected function login_clickHandler(event:MouseEvent):void
{
localComp.DoLoginStuff();
currentState = 'login';
}
]]>
</fx:Script>
精彩评论