flex 3 передает данные из модулей в родительское приложение для переключения представлений в стеке представлений

Привет, друзья, stackoverflowers!

Я застрял в написании кода. У меня есть приложение со стеком просмотра, которое загружает 5 модулей. каждый модуль загружается через тег moduleLoader, и все они имеют идентификатор.

У каждого загруженного модуля есть контекстное меню. контекстное меню имеет 5 пунктов меню. один элемент меню для каждого представления для стека представлений.

Контекстное меню загружается через xml.

это мой файл заявки.

<?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>

и это мой оператор переключения в моем модуле

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;
 }
}

а это мое контекстное меню 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>

Я бы хотел переключить представления в стеке представлений, щелкнув один из пунктов контекстного меню. я не могу связаться с моим модулем к приложению. Что я делаю неправильно? что мне делать? Кто-нибудь может мне помочь?

Ой, пока я не забыл

xml контекстного меню находится в модуле, но контекстное меню находится в файле as, который расширяет кнопку.

пожалуйста, может ли кто-нибудь дать мне хороший пример, как этого добиться.

Благодарить

DJ


person DJ.    schedule 11.01.2010    source источник
comment
Какую отладку вы уже сделали? Вы проверили, запускается ли ваша функция с помощью простой трассировки или Alert.show ()? Если ваша функция в модуле запускается, запускает ли она, в свою очередь, функцию в родительском приложении? Мне нравится делать общий Alert.show («уволен»); оператор и переместите его вниз по моей функции, чтобы убедиться, что каждая его часть срабатывает. Как только вы переместите его мимо чего-то, что вызывает ошибку, он выйдет из строя.   -  person invertedSpear    schedule 11.01.2010


Ответы (1)


Я вижу пару проблем, прежде чем перейти к многомодульной связи.

Сначала в функции changeView () вы объявляете действие переменной, а затем включаете его.

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

Поскольку в вашем операторе (-ах) switch нет случая «по умолчанию», parentApplication.switchView никогда не будет вызываться.

Кроме того, для краткости вы можете написать такие операторы переключения:

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;
}

Наконец, вы можете сэкономить еще больше времени на вводе текста, потому что ваши идентификаторы действий и модулей совпадают, вы можете сделать это:

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

Возможно, попробуйте эти вещи, а затем обновите свой вопрос (также, XML для ваших контекстных меню не отображался правильно в вашем вопросе). Это может помочь сообществу решить вашу проблему немного проще.

ОБНОВИТЬ

Не думаю, что проблема в модуле связи. Я создал простой проект, который, как мне кажется, делает то, что вы ищете. Я разместил источник ниже.

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>

Надеюсь, это поможет.

person RJ Regenold    schedule 11.01.2010
comment
спасибо за советы. Я отредактировал статус переключателя. Я также добавил дефолт. Несомненно, я все еще застрял. У вас еще есть другие советы, которые я могу дать? - person DJ.; 11.01.2010
comment
Спасибо за публикацию обновлений. То, как вы реализовали в переключателе вариант «по умолчанию», не совсем правильно. Я обновил свой код выше, чтобы показать, как следует использовать значение по умолчанию. Кроме того, откуда берется ваша переменная «действие»? Если он не слишком большой, не могли бы вы опубликовать код одного из своих модулей? - person RJ Regenold; 11.01.2010
comment
Опубликовать код было бы не так просто, потому что я реализую множество скриптов. Я могу отправить вам файлы моего проекта по электронной почте. Чтобы вы могли лучше рассмотреть это. - person DJ.; 11.01.2010
comment
на самом деле я не знаю, где разместить действие var - @action. Так было до публичной функции changeView (): void {var action: String; переключатель (действие) {//}} - person DJ.; 11.01.2010
comment
Я обновил свой ответ, чтобы предоставить небольшой образец приложения, которое делает то, что вы ищете. Дайте мне знать, если вам понадобится другая помощь. - person RJ Regenold; 11.01.2010
comment
Спасибо RJ, работаю :))). У меня есть другой вопрос, я хотел бы поместить сценарий в интерфейс. Как мне изменить сценарий, чтобы он работал (через интерфейс)? - person DJ.; 12.01.2010
comment
Без проблем. Я обновил свой ответ, чтобы показать, как можно реализовать интерфейс в основном классе приложения, а затем использовать этот интерфейс в модулях. Это то, что вы ищете? - person RJ Regenold; 13.01.2010
comment
@RJ Было бы лучше отправлять событие, чем создавать экземпляр родительского приложения и изменять его представление? Я думаю, что если модули действительно можно использовать повторно, тогда модуль не знает, какие представления доступны в родительском элементе. - person adamcodes; 02.02.2010
comment
Вы подали мне хороший пример ... Я только что посмотрел ваше небольшое приложение и выполнил свою работу по той же задаче ... Я хотел поставить вам 50 баллов ... поэтому я перешел к другим вашим ответам и увеличил количество голосов. . :) - person user533; 19.12.2012
comment
если возможно, не могли бы вы задать еще один мой вопрос .. (Пожалуйста) stackoverflow.com/questions/13935245/ - person user533; 19.12.2012