11 Replies Latest reply on Nov 14, 2006 1:23 AM by ljonny18

    dispatch event

    ljonny18 Level 1
      Hi - can someone help.....

      I have a simple query, but am not sure of the best way to go about doing it. I have read up on the events and given them a go, but have had no joy.

      Basically, for example, I have a main mxml file "main.mxml" containing a view stack linking to an additional 2 mxml components:

      <mx:ApplicationControlBar id="appBar_apc">
      <mx:LinkBar dataProvider="viewStack_vs"/>
      </mx:ApplicationControlBar>

      <mx:ViewStack id="viewStack_vs">
      <mi:page1 id="page_1" label="this is page 1"/>
      <mi:page2 id="page_2" label="this is page 2"/>
      </mx:ViewStack>

      I want to have a button in page1.mxml which when is clicked runs a function that is in page2.mxml!
      I guess an event can be dispatched that is listened for in page2.mxml and runs the function when it is dispatched etc.... although I can’t work out how to do this :(

      page1.mxml:
      <mx:button label=”click me” click=”run the testFunction in page2.mxml”/>

      page2.mxml
      public function testFunction()
      {
      Alert.show(“hello”);
      }

      Etc…..

      Can anyone help? or post an example for me?

      Thanks,
      Jon.
        • 1. Re: dispatch event
          leotemp Level 1
          How are there two "pages"? Are you saying you have two applications both running in sepperat instances like two web browsers? Or are you saying you have two different components "page 1" and "page 2" that are running inside your app and you need to communicate between them?
          • 2. Re: dispatch event
            ljonny18 Level 1
            yes the latter is correct:

            I have two different components "page 1" and "page 2" that are running inside my app and I need to communicate between them?

            Cheers,
            Jon.
            • 3. Re: dispatch event
              dimival Level 1
              You need to register an event listener to the viewStack component which will then call your function on the page2. The thing is that "brother" components (your pages which are inside a viewStack are brothers) can't listen to events of each other, but you can have their father (the viewstack in this case) listen to it and then tell them to do something.
              Please refer to the Flex Developers Guide for more information, but that's pretty much why your example is not working.
              • 4. Re: dispatch event
                peterent Level 2
                In software design, if you have a function in one unit that needs to be used in another unit, you should look to move that function to a more neutral place. In your case, it might be best if the function were in the Application itself. But of course, it depends on what the function does.

                Another thing that I see that not all of the UI objects in page2 will be available when the function is called from page1. For example, if that function on page2 were to set the text property of a <mx:TextInput> component, you would get an error because the ViewStack won't create the TextInput component until page2 becomes visible -- unless you set the creationPolicy on the ViewStack to "all" - another reason to think about your application's architecture.

                However, to this through events (this is how to do it without a custom event class)...

                1. Create a public var for page1 which will hold the value to be passed to the function on page2. If you need to pass multiple values, use either an Object with multiple properties or use multiple public vars.

                2. In page1, have the button click a) set the public variable(s), b) dispatchEvent(new Event(" page1click")) where "page1Click" is the name of the event from step 3.

                3. In page 1, add the following:
                <mx:Metadata>[Event(" page1click")]</mx:Metadata>
                This allows the compiler to generate the code to pass the event.

                4. In your main.mxml file, modify the page1 tag as:
                <mi:page1 id="page_1" label="this is page 1" page1click="page_2.thefunction(page_1.publicvar)" />
                where thefunction is the public function in page 2 that you want to call and page_1.publicvar is the public variable created in step 1 and set in step 2.
                • 5. Re: dispatch event
                  ljonny18 Level 1
                  Hi Peter, that is great and works a treat, thanks 

                  Although I now have another problem…:

                  I have a main mxml file "main.mxml" containing a view stack linking to an additional 2 mxml components:

                  <mx:ApplicationControlBar id="appBar_apc">
                  <mx:LinkBar dataProvider="viewStack_vs"/>
                  </mx:ApplicationControlBar>

                  <mx:ViewStack id="viewStack_vs">
                  <mi:page1 id="page_1" label="this is page 1"/>
                  <mi:page2 id="page_2" label="this is page 2"/>
                  <mi:page3 id="page_3" label="this is page 3"/>
                  <mi:page4 id="page_4" label="this is page 4"/>

                  <mi:page5 id="page_5" visible=”false”/>
                  <mi:page6 id="page_6” visible=”false”/>
                  <mi:page7 id="page_7" visible=”false”/>
                  </mx:ViewStack>

                  as you can see I have initialized all my pages within the viewStack within my main MXML file.
                  Although I want all the components to load within the viewStack, I don’t want to include all of the pages in the viewStack header (menu) as some of them will be linked / navigated to through button clicks within the main components and are not wanted / required in the viewStack menu item itself…..

                  I have tried setting the visible status = “false” and it removes the text from the menu item, although there is still a space (and rollover) there where the component is included…..

                  Can anyone tell me how I can remove these components from the viewStack menu item and / or initialize them elsewhere with them still being usable throughout the application….


                  Thanks,
                  Jon.
                  • 6. Re: dispatch event
                    peterent Level 2
                    Having the links respond to the rollover sounds like a bug; if I have time I'll check it out. In the meantime, I see that you have dataProvider="viewStack_vs" when I believe it should be dataProvider="{viewStack_vs}" - give that a whirl and see if the problem goes away.

                    The ViewStack does not, by default, create any of its children except the first one. Try setting creationPolicy="all" on the ViewStack and see if that makes a difference.

                    Lastly, try adding enabled="false" to the pages with visible="false" - perhaps that will discourage the LinkBar from displaying them.

                    As I said, I've not tried your code; these are just guesses at the moment.
                    • 7. dispatch event
                      ljonny18 Level 1
                      Hi Peter. I tried all of that - but I had no joy :(

                      I don’t know if I explained it properly, so let me try again:

                      As before, my menu id set up including a linkBar within an applicationControlBar populated (dataProvider) by the viewStack (as before) :

                      <mx:ApplicationControlBar id="appBar_apc">
                      <mx:LinkBar dataProvider="{viewStack_vs}"/>
                      </mx:ApplicationControlBar>

                      <mx:ViewStack id="viewStack_vs">
                      <mi:page1 id="page_1" label="this is page 1"/>
                      <mi:page2 id="page_2" label="this is page 2"/>
                      <mi:page3 id="page_3" label="this is page 3"/>
                      <mi:page4 id="page_4" label="this is page 4"/>

                      <mi:page5 id="page_5" visible=”false”/>
                      <mi:page6 id="page_6” visible=”false”/>
                      <mi:page7 id="page_7" visible=”false”/>
                      </mx:ViewStack>


                      Basically I want the application to only show / display (within the viewStack) :
                      - page 1
                      - page 2
                      - page 3
                      - page 4

                      and not page 5, 6 and 7 etc… which was what I was trying to do by setting the visible=”false” property - and also having no label text ….
                      I have now also added the enabled=”false” property as you suggested, although it seems to have made no difference (apart from removing the rollover effect) :(

                      It is hard to explain the output, but it looks something like this:

                      page 1 | page 2 | page 3 | page 4 | | | |

                      And I don’t want the (blank) spaces to appear after "page 4" – where 5, 6 and 7 should be etc……


                      I hope this makes things clearer in terms as to what I am trying to do ???

                      Thanks again,
                      Jon.

                      • 8. Re: dispatch event
                        peterent Level 2
                        In the clearer air of morning I realized that the visible setting of the child won't affect the LinkBar at all. The LinkBar shows the labels of all of the children of the ViewStack. Howver, I did some experimentation and came up with 2 choices. In both cases the pages 5-7 cannot be part of the ViewStack, so just drop them.

                        Choice #1:
                        When you know you want to display say, page 5, create it if not already created, then add it to the ViewStack:

                        var p5:page5;
                        if( p5 == null ) {
                        p5 = new page5();
                        p5.label = "Page 5";
                        // set styles, etc.
                        }
                        ViewStack_vs.addChild(p5);
                        ViewStack_vs.selectedChild = p5;

                        This will add page5 to the viewstack and select it. It will also put the LinkButton for the page into the LinkBar.

                        You will also need to listen for the change event on the viewstack so you can remove page5 when another Link has been clicked:

                        private function changeviewstack( event:Event ) : void {
                        if( event.target.selectedChild != page5 ) event.target.removeChild(page5);
                        }

                        Note that removing the child from the viewstack does not destroy it -it just removes it from the viewstack's display list. This way you only create it once and just add and remove it as necessary. Do the same for the other pages.


                        Choice #2:
                        Place another ViewStack directly ontop of the ViewStack_vs and let it contain page5 - page7. Make this ViewStack invisible.

                        When you need to show, say page 5, make the alternate ViewStack visible (you may want to make the _vs invisible so none of it shows accidently).

                        The latter solution is easier to do and can be set up in MXML; the former solution allows the extra pages to appear temporarily in the LinkBar, giving some continuuty to the application.
                        • 9. Re: dispatch event
                          ljonny18 Level 1
                          Hi Peter - I used "Choice 2" and it works....

                          although, I have one problem / querey:

                          When you say "Make this ViewStack invisible" - I assume you mean set the visible property = falase (visible="false") within the viewStack ??? which is what I have done.....

                          but, althought you cant see any of the content of the (2nd) viewStack, you can see where is is in terms of the screen space it takes up!
                          i.e. if I only have a mx:button then about 2cm of screen space (where this 2nd "invisible" viewStack is) above the 1st "visible" viewStack, whereas, if I have an mx:dataGrid with a height set to about 50pixels etc... then 50pixels of screen space is taken up in this case and thus the 1st "visible" viewStack is pushed-down 50pixels and displayed there etc..........

                          mmm, does this make sense??? if not I will try to explain myself better!

                          I thought, maybe if there is no real solution to this (or I am just doing something wrong), then maybe playing with the height variables of the viewStacks could possibly solve things...... but I am not sure of the best "work-around" in this case.


                          thanks again,
                          Jon.
                          • 10. Re: dispatch event
                            peterent Level 2
                            Let's assume your ViewStacks are in an Application file - at the top level so they are direct children of the Application.

                            If the Application's layout="absolute" then it acts like a Canvas and you can position items on top of each other:

                            <mx:Button x="20" y="20" label="B1" />
                            <mx:Button x="20" y="20" label="B2" />

                            You will see B2 over B1 because the first one is lower (depth) than the ones later.

                            You should place your ViewStacks into a Canvas (or any container that allows absolute positioning). You could even, brace yourself, use a ViewStack:

                            Choice #3: (wish I thought of this earlier)

                            <mx:ViewStack id="outer">
                            --- <mx:ViewStack id="p1_p4">
                            ------- <page1 ... />
                            ------- <page 2... />
                            ------- <page 3.../>
                            ------- <page 4.../>
                            --- </mx:ViewStack>
                            --- <mx:ViewStack id="p5_p6">
                            ------- <page5 ... />
                            ------- <page6 .../>
                            --- </mx:ViewStack>
                            </mx:ViewStack>

                            I used -- to make the indentation work so you would see the arrangement. The outer ViewStack does all the work of Choice 2. Sorry I didn't think of that earler.
                            • 11. Re: dispatch event
                              ljonny18 Level 1
                              thats great, it works a treat!

                              thanks Peter, its appreciated :)

                              Jon.