Flex 4 удаляет пользовательское событие из пользовательского компонента - PullRequest
0 голосов
/ 16 февраля 2012

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

Примечание: ошибка генерируется из родительского пользовательского компонента (третий фрагмент кода), я добавил туда более подробную информацию

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

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 и просто направляет событие слушателям.Проверьте теги meatadata.Регистрация событий выполнена правильно.

Однако ошибка приходит на

           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>

Ответы [ 4 ]

2 голосов
/ 16 февраля 2012

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

1 голос
/ 02 марта 2012

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

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

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

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

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

0 голосов
/ 23 сентября 2013

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

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

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

0 голосов
/ 16 февраля 2012

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

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

...