Flex 4 отключает пользовательское событие от пользовательского компонента

Это похоже на вопрос, заданный здесь. Я отправляю настраиваемое событие «ShopEvent», но получаю сообщение об ошибке «Ошибка приведения типа: невозможно преобразовать flash.events::Event@81ecb79 в com.events.ShopEvent»

Примечание. Ошибка возникает из-за родительского пользовательского компонента (3-й фрагмент кода), я добавил туда дополнительные сведения

Это мое индивидуальное мероприятие. Смотрите первую константу, я копирую вставленное имя события в пользовательские компоненты.

package com.events
{
    import flash.events.Event;

    public class ShopEvent extends Event
    {

        public static var MENU_SELECTED:String = "menuSelected";
        public static var SUBMENU_SELECTED:String = "submenuSelected";
        public static var ITEM_SELECTED:String = "itemSelected";
        public static var NAV_NEXT:String = "navNext";
        public static var NAV_PREVIOUS:String = "navPrevious";
        public static var NAV_LAST:String = "navLast";
        public static var NAV_FIRST:String = "navFirst";
        public static var CLOSE:String = "close";

        public var menuIdx:int;
        //public var menuType:String;
        public var menuId:int;
        public var menuName:String;
        public var itemId:int;
        public function ShopEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
        {
            super(type, bubbles, cancelable);
        }
    }
}

Пользовательский компонент. Проверьте теги метаданных. Событие зарегистрировано правильно

<?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="72" height="82"
         mouseChildren="false"
         creationComplete="init()"
         click="onClick()"
         buttonMode="true">
    <s:layout>
        <s:VerticalLayout horizontalAlign="center"/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import com.events.ShopEvent;

            import mx.controls.Image;
            public var menuId:int;

            [Bindable]
            public var menuText:String;
            [Bindable]
            public var bmp:Bitmap;

            private function init():void{
                //img.addChild(bmp);
            }
            private function onClick():void{
                var e:ShopEvent = new ShopEvent(ShopEvent.MENU_SELECTED);
                e.menuId = menuId;
                e.menuName = menuText;
                dispatchEvent(e);
            }

        ]]>

    </fx:Script>
    <fx:Metadata>
        [Event(name="menuSelected", type="com.events.ShopEvent")]
    </fx:Metadata>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Label text="{menuText}" fontWeight="bold" fontSize="12" width="44"/>
    <mx:Image id = "img" width="57" height="47" source="{bmp}"/>

</s:Group>

Родительский пользовательский компонент. Это родительский компонент указанного выше пользовательского компонента. Он прослушивает событие menuSelected и просто направляет событие в списки. Проверьте теги мясных данных. Регистрация на мероприятие сделана правильно.

Однако ошибка возникает на

           menus[i].addEventListener( ShopEvent.MENU_SELECTED,function(e:ShopEvent):void{dispatchEvent(e);});

насколько мне известно, я не вижу проблем в коде. Что в этом плохого?

Обновить

Удивительно, но если я создам «новый» экземпляр shopwevent, это решит проблему, но, к сожалению, мне нужно закрыть все свойства объекта события. Надеюсь, это не ограничение гибкости.

                menus[i].addEventListener( ShopEvent.MENU_SELECTED,function(e:ShopEvent):void{dispatchEvent(new ShopEvent(ShopEvent.MENU_SELECTED));});

Полный код

<?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="720" height="605"
         creationComplete="init()" xmlns:shop="UI.shop.*" xmlns:hasu="UI.shop.hasu.*"
         >
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Metadata>
        [Event(name="navNext", type="com.events.ShopEvent")]
        [Event(name="navPrevious", type="com.events.ShopEvent")]
        [Event(name="menuSelected", type="com.events.ShopEvent")]
        [Event(name="submenuSelected", type="com.events.ShopEvent")]
        [Event(name="itemSelected", type="com.events.ShopEvent")]
        [Event(name="close", type="com.events.ShopEvent")]
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            import com.events.ShopEvent;

            private const MAX_SLOTS:int = 6;

            public var menus:Vector.<ShopMenuItemView>;
            public var itemSlots:Vector.<ShopItemSlotView> = new Vector.<ShopItemSlotView>(MAX_SLOTS);

            private function init():void{
                trace("BEGIN:UI.shop.hasu.ShopView.init");
                initSlots();
            }

            private function initSlots():void{

                for (var i:int = 0;i<itemSlots.length;i++){
                     var slot:ShopItemSlotView = new ShopItemSlotView();
                    itemSlots[i] = slot; 
                    itemSlotsContainer.addElement(slot);
                }
            }

            public function initMenus():void{
                trace("BEGIN:UI.shop.hasu.ShopView.initMenus");
                for (var i:int = 0;i < menus.length;i++){
                    menuContainer.addElement(menus[i]);
                    menus[i].addEventListener(ShopEvent.MENU_SELECTED,function(e:ShopEvent):void{dispatchEvent(e);});
                    //menus[i].addEventListener( ShopEvent.MENU_SELECTED,function(e:ShopEvent):void{dispatchEvent(new ShopEvent(ShopEvent.MENU_SELECTED));});
                }
            }



        ]]>
    </fx:Script>

    <s:layout>
        <s:VerticalLayout />
    </s:layout>
    <s:VGroup name="top">
        <hasu:ShopPlayerAttributesView id="attribsComp"/>
        <s:Group id="menuContainer" name="menus">
            <s:layout>
                <s:HorizontalLayout />
            </s:layout>
        </s:Group>
    </s:VGroup>
    <s:Group>
        <s:layout>
            <s:HorizontalLayout />
        </s:layout>
        <s:Button label="&lt;" />
        <s:Group id = "itemSlotsContainer" name="items">
            <s:layout>
                <s:TileLayout requestedColumnCount="3" requestedRowCount="3"/>
            </s:layout>
        </s:Group>
        <s:Button label="&gt;" />
    </s:Group>
</s:Group>

person dejjub-AIS    schedule 16.02.2012    source источник


Ответы (4)


Вы должны перезаписать метод clone () для пользовательских классов событий. Во время распространения события можно было клонировать несколько раз.

person Jack    schedule 16.02.2012
comment
Жалко, но у меня работает. То, что я сделал в clone (), просто вернул экземпляр this. Но что-то идет не так, мой список событий вообще не запускается. (это происходит, если я создаю новый экземпляр и передаю новый intance (не клонированный)) - person dejjub-AIS; 16.02.2012
comment
Я прочитал документацию. Это действительно неудобно, мне нужно создать новый экземпляр и скопировать все свойства. почему эта AS реализовала это таким образом? - person dejjub-AIS; 16.02.2012

Ответ Джека правильный. Это приведено в документации по гибкости.

Вам необходимо переопределить метод Event.clone () в своем подклассе. Метод clone () возвращает клонированную копию объекта события, задав свойство type и любые новые свойства в клоне. Обычно вы определяете метод clone () для возврата экземпляра события, созданного с помощью оператора new.

Для получения полной информации см. Работа с событиями в разделе создание подкласса из раздела события

Хорошее место для понимания пользовательских событий для новых разработчиков flex / as3, чтобы прочитать Отправка пользовательских событий

Примечание: ссылки указывают на документацию Flex 4.6, но часть настраиваемых событий не зависит от версии (только часть mxml может отличаться для Flex 3 и предыдущих версий)

person dejjub-AIS    schedule 02.03.2012
comment
Если ответ Джека правильный, вы должны принять его ответ, а не свой собственный. - person Marty Pitt; 02.03.2012
comment
@MartyPitt Я надеялся, что мой ответ, в котором есть немного более подробной информации, поможет кому-то там. и да, я уже принял его ответ - person dejjub-AIS; 22.11.2012

вы должны вернуть новый конструктор класса события, например:

return new ShopEvent(type,...); //in the clone() method;

Метод clone() возвращает клонированную копию объекта события, задав свойство type и любые новые свойства в клоне. Обычно вы определяете метод clone() для возврата экземпляра события, созданного с помощью оператора new.

person Nagaraju    schedule 23.09.2013

Отправляемое вами событие относится к типу flash.events.Event, а событие, которое ожидает ваш слушатель, - к типу: com.events.ShopEvent.

Это просто то, что означает сообщение об ошибке.

person Ilya Gazman    schedule 16.02.2012
comment
вы только что предложили на основе сообщения об ошибке? Я уверен, что создаю и передаю экземпляры ShopEvent. Вы можете указать, в какой строке могла быть ошибка? - person dejjub-AIS; 16.02.2012
comment
меню [i] .addEventListener (ShopEvent.MENU_SELECTED, функция (e: ShopEvent): void {dispatchEvent (e);}); - person dejjub-AIS; 16.02.2012