5 Replies Latest reply on Feb 4, 2011 9:27 PM by memBrainStudios

    How do you access parent component from a child in Flex 4?

    memBrainStudios Level 1

      Suppose I have a Component A (as a Spark Group) that generates an event, eventX.  Inside Component A, I add Component B (also a Spark Group) that wants to add itself as an event listener for eventX.  How do I access Component A from Component B to register for the event?

       

      For reference, this relationship should be similar to the MVC pattern where Component B is the view, and Component A is the model and controller.

       

      If I were implementing this in ActionScript, I'd have no problem coding this.  However, I am using flex, and am still trying to figure out how the FLEX API works.

        • 1. Re: How do you access parent component from a child in Flex 4?
          _spoboyle Level 4

          Main.mxml

          <?xml version="1.0" encoding="utf-8"?>
          <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                                 xmlns:s="library://ns.adobe.com/flex/spark"
                                 xmlns:mx="library://ns.adobe.com/flex/mx"
                                 xmlns:local="*">
             
              <fx:Script>
                  <![CDATA[

           

                      protected function clickHandler(event:MouseEvent):void
                      {
                          dispatchEvent(event);
                      }

           

                  ]]>
              </fx:Script>
             
              <s:VGroup>
                  <s:Button label="click me" click="clickHandler(event)"/>
                  <local:MyLabel id="myLabel"/>
              </s:VGroup>
             
          </s:WindowedApplication>

           

          MyLabel.mxml

          <?xml version="1.0" encoding="utf-8"?>
          <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   creationComplete="init()">
             
              <fx:Script>
                  <![CDATA[
                      private function init():void
                      {
                          parent.addEventListener(MouseEvent.CLICK, eventHandler);
                          parent.addEventListener(MouseEvent.MOUSE_OVER, eventHandler);
                          parent.addEventListener(MouseEvent.MOUSE_OUT, eventHandler);
                      }
                     
                      private function eventHandler(e:Event):void
                      {
                          myLabel.text = e.type;
                      }
                  ]]>
              </fx:Script>
             
              <fx:Declarations>
                  <!-- Place non-visual elements (e.g., services, value objects) here -->
              </fx:Declarations>
             
              <s:Label id="myLabel"/>
          </s:Group>

          • 2. Re: How do you access parent component from a child in Flex 4?
            GordonSmith Level 4

            B could "reach up" to A using the parentDocument property. Or you could set a reference-to-A onto B.

             

            Gordon Smith

            Adobe Flex SDK Team

            • 3. Re: How do you access parent component from a child in Flex 4?
              memBrainStudios Level 1

              GordonSmith wrote:

               

              B could "reach up" to A using the parentDocument property. Or you could set a reference-to-A onto B.

               

              Gordon Smith

              Adobe Flex SDK Team

               

              B could "reach up" to A using the parentDocument property

              Would you mind explaining that?

               set a reference-to-A onto B.

              That is something I am trying to avoid.  I do not want to create tightly coupled code.

               

              Here is a generic form of the code I am using.  Feel free to tell me what I'm doing wrong in your explanation of how B can "reach up" to A.  Thanks!

               

              Component A

              <?xml version="1.0" encoding="utf-8"?>
              <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
                         xmlns:s="library://ns.adobe.com/flex/spark" 
                         xmlns:mx="library://ns.adobe.com/flex/mx" width="837" height="733" 
                               creationComplete="componentA_creationCompleteHandler(event)"
                               xmlns:components="components.*">
                   <fx:Script>
                        <![CDATA[
                             import mx.events.FlexEvent;
              
                             public static const STATE_CHANGED:String = "stateChanged";
                             private var currentModelState:String;
              
                             protected function componentA_creationCompleteHandler(event:FlexEvent):void
                             {
                                  changeModelState("second");
                             }
              
                             public function changeModelState(newState:String):void
                             {
                                  if (newState != currentModelState)
                                  {
                                       currentModelState = newState;
                                  }
                                  
                                  dispatchEvent(new Event(IP_Dragon.STATE_CHANGED));
                             }
                             
                             public function getModelState():String
                             {
                                  return currentModelState;
                             }
                        ]]>
                   </fx:Script>
                   <fx:Declarations>
                        <!-- Place non-visual elements (e.g., services, value objects) here -->
                   </fx:Declarations>
                   <components:Component_B id="b" x="0" y="0"/>
              </s:Group>
              

               

              Component B

              <?xml version="1.0" encoding="utf-8"?>
              <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
                         xmlns:s="library://ns.adobe.com/flex/spark" 
                         xmlns:mx="library://ns.adobe.com/flex/mx"
                         xmlns:components="components.*"
                         width="837" height="733" contentBackgroundAlpha="0.0" currentState="first"
                         creationComplete="componentB_creationCompleteHandler(event)">
                   <fx:Script>
                        <![CDATA[
                             import mx.events.FlexEvent;
              
                             protected function componentB_creationCompleteHandler(event:FlexEvent):void
                             {
                                  currentState = parent.getModelState;
                                  parent.addEventListener(Component_A.STATE_CHANGED, modelStateListener);
                             }
              
                             private function modelStateListener (e:Event):void
                             {
                                  currentState = parent.getModelState();
                             }
                        ]]>
                   </fx:Script>
                   <s:states>
                        <s:State name="first"/>
                        <s:State name="second"/>
                        <s:State name="third"/>
                   </s:states>
                   <fx:Declarations>
                        <!-- Place non-visual elements (e.g., services, value objects) here -->
                   </fx:Declarations>
                   <components:Component_C includeIn="first" x="220" y="275"/>
                   <components:Component_D includeIn="second" x="2" y="0"/>
                   <components:Component_E includeIn="third" x="0" y="8"/>
              </s:Group>
              

               

              For the record, I know this code does not work.  It has to do with the parent calls in Component B.  Comment out those lines, and the code will compile.

              • 4. Re: How do you access parent component from a child in Flex 4?
                memBrainStudios Level 1

                Strange...the two words highlighted in red on Component A are supposed to be encapsulated in quotes.  At least that's how they are in my file.  Not sure what happened there.

                • 5. Re: How do you access parent component from a child in Flex 4?
                  memBrainStudios Level 1

                  I have figured out the problem.  Yes, it had to do with navigating up the parentDocument.  Here is my solution:

                   

                  Component B

                  <?xml version="1.0" encoding="utf-8"?>
                  <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
                             xmlns:s="library://ns.adobe.com/flex/spark" 
                             xmlns:mx="library://ns.adobe.com/flex/mx"
                             xmlns:components="components.*"
                             width="837" height="733" contentBackgroundAlpha="0.0" currentState="first"
                             creationComplete="componentB_creationCompleteHandler(event)">
                       <fx:Script>
                            <![CDATA[
                                 import mx.events.FlexEvent;
                  
                                 protected function componentB_creationCompleteHandler(event:FlexEvent):void
                                 {
                                      var temp:Component_A = parentDocument as Component_A;
                                      currentState = temp.getModelState();
                                      temp.addEventListener(Component_A.STATE_CHANGED, modelStateListener);
                                 }
                  
                                 private function modelStateListener (e:Event):void
                                 {
                                      var temp:Component_A = parentDocument as Component_A;
                                      currentState = temp.getModelState();
                                 }
                            ]]>
                       </fx:Script>
                       <s:states>
                            <s:State name="first"/>
                            <s:State name="second"/>
                            <s:State name="third"/>
                       </s:states>
                       <fx:Declarations>
                            <!-- Place non-visual elements (e.g., services, value objects) here -->
                       </fx:Declarations>
                       <components:Component_C includeIn="first" x="220" y="275"/>
                       <components:Component_D includeIn="second" x="2" y="0"/>
                       <components:Component_E includeIn="third" x="0" y="8"/>
                  </s:Group>
                  

                   

                  No changes were required of Component A.  I have tested this and it works as intended.  Thanks for the help pointing me in the right direction!