2 Replies Latest reply on Aug 22, 2007 10:52 AM by L_M

    best pattern to signal a parent control from a deeply nested child control

    L_M
      #1
      The application i created hosts intially a logincontrol.

      The login control signals the application with OnAuthenticationPassed to move states.
      This state change removes the login control and loads the administration control.

      this one level nesting is okay to be handled by having the parent listen to an event the child makes... but when multiple levels of nesting occurs... chaining events just to propagate the message up .. is not a flexible solution... example:


      The administration control hosts a lot of specific task controls.
      [ArticleManagement - (contains categorymanagement, new article, edit article -- further nesting controls)]

      eventually the session will die out on the server... so when a task (example: submit new article) the server response will be:
      <response>
      <isAuthenticated value="false" />
      </response>

      I will then have to propagate this message up to the application parent level so that administration control panel is removed and replaced with the login control.


      what is the best way to handle this?

      #2
      what are common transition patterns when removing one panel and putting another in its place? [i'm an application developer not an animator.]


      thanks,

      Leblanc Meneses
        • 1. Re: best pattern to signal a parent control from a deeply nested child control
          peterent Level 2
          You want to use event bubbling. Consider a control that's several level down and you want an event generated by that control needs to be intercepted at the higher, application level. A good example is a click inside of an itemRenderer that you want to grab in the Application.

          In the component that you want to dispatch event, you do:
          var e:Event = new Event("yourEventType",true); // the true indicates the event will bubble
          dispatchEvent(e);

          In the Application, add an event handler for the "yourEventType" on the component in which the target component exists. Now you can easily send information from a nested component to any level higher.

          As for your next question There are a couple of ways to do this. Whenever I have 2 or more components that need to occupy the same space and only 1 of the components is visible at any time, I use a ViewStack. So you have 2 Panels that you want to swap.

          <mx:ViewStack id="stack">
          <mx:Panel id="firstPanel" ...> <!-- contents of the panel --> </mx:Panel>
          <mx:Panel id="secondPanel" ...> <!-- contents of the panel --> </mx:Panel>
          </mx:ViewStack>

          Now swap the panels by telling the ViewStack which one you want to see: stack.selectedChild=firstPanel (or stack.selectedIndex=0). Fine, but you want some animation.

          There are a number of effects you can use. A nice easy one is to slide on panel out while another slides in. So you declare some Move effects (just above the ViewStack is a good place):

          <mx:Move id="slideLeft" xTo="0" xFrom="-1000" />
          <mx:Move id="slideRight" xTo="1000" xFrom="0" />

          Now apply them to the panels, setting the hideEffect and showEffect on each panel:

          <mx:Panel id="firstPanel" showEffect="slideLeft" hideEffect="slideRight" /> and ditto for the secondPanel. The ViewStack will take care of activating the running the effects - you don't have to d anything else.

          Experiment with the various effects (like Wipes, Fades, Zooms) - you can event combine them with the Parallel and Sequence effects.
          • 2. Re: best pattern to signal a parent control from a deeply nested child control
            L_M Level 1
            thanks for the bubbling information. for a minute I thought i had to create a singleton to centralize registering events. I'm glad the framework manages this inside UIComponent .. less things i have to worry about.


            about animiation: thanks first of all.. looking nice now.

            my current implementation works but you can see where the viewstack starts and ends by when the control and leaves, enters the scene through the animation.

            If i change the viewstack width and height to 100% i loose the ability to center the inner contents...

            i want the viewstack width and height to 100% and still be able to center vertically and horizontally the inner contents. do you know how to do this?


            Thanks again,

            Leblanc Meneses


            <mx:states>
            <mx:State name="OnAuthenticationPassed">
            <mx:SetProperty name="selectedChild" target="{this.viewstack1}" value="{this.administrationmain1}" />
            </mx:State>
            </mx:states>


            <mx:Script>
            <![CDATA[

            import flash.events.*;
            import mx.effects.easing.Bounce;

            public function init():void
            {
            //register to global event manager
            this.addEventListener("OnAuthenticationPassed", OnAuthenticationPassed);
            this.addEventListener("OnAuthenticationFailed", OnAuthenticationFailed);
            }

            private function OnAuthenticationPassed(event:Event):void
            {
            this.currentState="OnAuthenticationPassed";
            }

            private function OnAuthenticationFailed(event:Event):void
            {
            this.currentState="";
            this.viewstack1.selectedChild = this.login1;
            }

            ]]>
            </mx:Script>


            <mx:Parallel id="outEffect">
            <mx:Dissolve duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
            <mx:Move duration="500" xTo="-9000" xFrom="0" />
            </mx:Parallel>
            <mx:Parallel id="inEffect">
            <mx:Dissolve duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
            <mx:Move duration="500" xTo="0" xFrom="-9000" />
            </mx:Parallel>
            <mx:ViewStack id="viewstack1" resizeToContent="true" horizontalCenter="0" verticalCenter="-5">
            <comp:login id="login1"
            hideEffect="{this.outEffect}" showEffect="{this.inEffect}" />
            <administration:administrationmain id="administrationmain1"
            hideEffect="{this.outEffect}" showEffect="{this.inEffect}" />
            </mx:ViewStack>