views:

2015

answers:

1

Hello Fellow stackoverflowers,

I´m stuck writing a piece of code. I have application with a viewstack witch load 5 modules. each module is loaded via the moduleLoader tag and they all have an id.

Every loaded module has a context menu. the context menu has 5 menuItems. one menuItem for each view for the viewstack.

The context menu is loaded via xml.

this is my application file.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
      layout="absolute"
      backgroundColor="#b1b1b1"
      backgroundGradientColors="[#b1b1b1,#252525]">

<mx:Script>
<![CDATA[
import mx.core.Container;


        //change viewstack views via modules context menu
        public function switchView(viewId:String):void
     {
         var container:Container = Container(tops.getChildByName(viewId));
         if (container != null)
         {
             tops.selectedChild = container;
         }
     }
]]>
</mx:Script>

<mx:ViewStack id="tops" width="100%" height="100%">
  <mx:ModuleLoader id="admin" url="view/admin.swf" width="100%" height="100%"/>
  <mx:ModuleLoader id="tv" url="view/tv.swf" width="100%" height="100%"/>
  <mx:ModuleLoader id="community" url="view/community.swf" width="100%" height="100%"/>
  <mx:ModuleLoader id="shop" url="view/shop.swf" width="100%" height="100%"/>
  <mx:ModuleLoader id="communicator" url="view/communicator.swf" width="100%" height="100%"/>
</mx:ViewStack>


</mx:Application>

and this is my switch statement in my Module

public function changeView():void{
switch(action) {
case "admin":
    parentApplication.switchView("admin");
break;
case "tv":
    parentApplication.switchView("tv");
break;
case "shop":
    parentApplication.switchView("shop");
break;
case "community":
    parentApplication.switchView("community");
break;
case "default":
    parentApplication.switchView("communicator");
break;
 }
}

and this is my context menu xml

  <mx:XML id="appMenu">
    <root>
        <menuitem enabled="false"/>
        <menuitem label="Administration" action="admin" icon="adminMDI"/>
        <menuitem label="Television" action="tv" icon="tvMDI"/>
        <menuitem label="Community" action="community" icon="communityMDI"/>
        <menuitem label="Shopping Mall" action="shop" icon="shoppingMallMDI"/>
        <menuitem label="Communicator" action="default" icon="communicatorMDI"/>                                                              
    </root>
  </mx:XML>

What i would like to do is switch the views in the viewstack by clicking on one of the menuitems in the context menu. i can't communicate from my module to the application. What am i doing wrong? what must i do? Can anybody help me out?

Oyeah before i forget

the xml of the context menu is in the module but, the context menu is in a as file that extensiate a button.

please can any body give me a good example how to accomplish this.

Thank

DJ

+3  A: 

I see a couple issues before getting into the multi-module communication.

First, in your changeView() function, you are declaring the variable action and then switching on it.

public function changeView():void {
    var action:String;
    switch(action) {
        // action will always be null here.
    }
}

Because you don't have a 'default' case in your switch statement(s), parentApplication.switchView will never be called.

Also, for the sake of brevity, you can write switch statements like this:

switch(action) {
    case "admin":
        parentApplication.changeView("admin");
    break;
    case "tv":
        parentApplication.changeView("tv");
    break;
    case "shop":
        parentApplication.changeView("shop");
    break;
    // ... etc ...
    default:
        // this gets called if action doesn't match anything.
    break;
}

Finally, you could save yourself even more typing because your action and module ids are the same, you could do this:

public function changeView(action:String):void {
    parentApplication.changeView(action);
}

Maybe try those things and then updating your question (also, the XML for your context menus didn't render correctly in your question). That may help the community solve your issue a little easier.

UPDATE

I don't think the problem is in the module communication. I built a simple project that does what I think you're looking for. I've posted the source below.

mmodules.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" implements="interfaces.IApplication">
    <mx:Script>
        <![CDATA[
            import mx.core.Container;
            public function changeView(action:String):void {
                viewstack.selectedChild = viewstack.getChildByName(action) as Container;
            }
        ]]>
    </mx:Script>
    <mx:ViewStack id="viewstack" width="100%" height="100%">
        <mx:ModuleLoader id="module1" url="views/module1.swf" />
        <mx:ModuleLoader id="module2" url="views/module2.swf" />
    </mx:ViewStack>
</mx:Application>

interfaces/IApplication.as

package interfaces {
    public interface IApplication {
        function changeView(action:String);
    }
}

views/module1.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import interfaces.IApplication;
            import mx.events.MenuEvent;
            import mx.controls.Menu;
            /**
            * Dynamically builds a menu.
            */
            protected function showMenu():void {
                var m:Menu = Menu.createMenu(null, menuData, false);
                m.labelField = '@label';
                m.addEventListener(MenuEvent.ITEM_CLICK, onItemClick);
                m.show(10, 10);
            }
            /**
            * Handles whenever an item in the menu is clicked.
            */
            protected function onItemClick(e:MenuEvent):void {
                if(e && e.item && e.item is XML) {
                    changeView(e.item.@action);
                }
            }
            /**
            * Tells the parent application to switch views.
            */
            protected function changeView(action:String):void {
                var app:IApplication = parentApplication as IApplication;
                switch(action) {
                    case 'module1':
                        app.changeView('module1');
                    break;
                    case 'module2':
                        app.changeView('module2');
                    break;
                }
            }
        ]]>
    </mx:Script>
    <mx:XML format="e4x" id="menuData">
        <root>
            <menuitem label="Module 1" action="module1" />
            <menuitem label="Module 2" action="module2" />
        </root>
    </mx:XML>
    <mx:Button label="Show menu" click="showMenu()" />
</mx:Module>

Hope that helps.

RJ Regenold
thanks for the tips. I have edited the switch Statment. I have also thrown in a default. Unfornutatly i'm still stuck. Do you still have other tips i can chech out?
DJ
Thank you for posting updates. The way you implemented the 'default' case in the switch isn't quite correct. I updated my code above to show how default should be used. Also, where is your 'action' variable coming from? If it's not too large, would you mind posting the code from one of your modules?
RJ Regenold
To post the code would not be so simple because i implement a lot of scripts. i can send you my project files by email. So that you can have a better look at it.
DJ
actually i don't know where to put the action var - @action.I had it like this beforepublic function changeView():void { var action:String; switch(action) { // }}
DJ
I updated my answer to provide a small sample application that does what you're looking for. Let me know if you need any other help with it.
RJ Regenold
Thanks RJ, I works :))). I have another question, i would like to put the script in an interface, How must i alter the script to let it work (via Interface)?
DJ
No problem. I updated my answer to show how you could have the main application class implement an interface, then use that interface in the modules. Is that what you're looking for?
RJ Regenold
yes, thank you. I will try it out
DJ
@RJ Would it be a better approach to dispatch an event as opposed to creating an instance of the parent app and changing it's view? I'm thinking if the modules are truly reusable, then the module doesn't know what views are available at the parent.
adamcodes