Apache flex Flex 4从自定义组件中分离自定义事件
这与所问的问题类似。我正在发送自定义事件“ShopEvent”,但收到错误“类型强制失败:无法转换flash。事件::Event@81ecb79到com.events.ShopEvent“ 注意:错误是从父自定义组件(第三个代码段)抛出的,我在那里添加了更多详细信息 这是我的定制活动。请参见第一个常量,我在自定义组件中复制粘贴了事件名称Apache flex Flex 4从自定义组件中分离自定义事件,apache-flex,event-handling,custom-component,custom-events,Apache Flex,Event Handling,Custom Component,Custom Events,这与所问的问题类似。我正在发送自定义事件“ShopEvent”,但收到错误“类型强制失败:无法转换flash。事件::Event@81ecb79到com.events.ShopEvent“ 注意:错误是从父自定义组件(第三个代码段)抛出的,我在那里添加了更多详细信息 这是我的定制活动。请参见第一个常量,我在自定义组件中复制粘贴了事件名称 package com.events { import flash.events.Event; public class 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>
据我所知,代码中没有任何问题。有什么不对劲吗
更新
令人惊讶的是,如果我创建一个shopwevent的“新”实例将解决这个问题,但遗憾的是,我需要关闭事件对象的所有属性。我希望这不是flex的限制
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="<" />
<s:Group id = "itemSlotsContainer" name="items">
<s:layout>
<s:TileLayout requestedColumnCount="3" requestedRowCount="3"/>
</s:layout>
</s:Group>
<s:Button label=">" />
</s:Group>
</s:Group>
[事件(name=“navNext”,type=“com.events.ShopEvent”)]
[事件(name=“navPrevious”,type=“com.events.ShopEvent”)]
[事件(name=“menuSelected”,type=“com.events.ShopEvent”)]
[事件(name=“submenuSelected”,type=“com.events.ShopEvent”)]
[事件(name=“itemSelected”,type=“com.events.ShopEvent”)]
[事件(name=“close”,type=“com.events.ShopEvent”)]
;
公共var itemSlots:Vector.=新向量(最大时隙);
私有函数init():void{
trace(“BEGIN:UI.shop.hasu.ShopView.init”);
initSlots();
}
私有函数initSlots():void{
对于(变量i:int=0;i
您正在调度的事件来自flash.events.event类型,而侦听器期望的事件来自com.events.ShopEvent类型
这就是错误消息的含义。您必须覆盖自定义事件类的clone()方法。在传播过程中,事件可以被克隆多次。Jack的回答是正确的。flex文档中给出了这个答案 您需要重写应用程序中的Event.clone()方法 clone()方法返回事件对象的克隆副本 通过在克隆中设置类型属性和任何新属性。 通常,定义clone()方法以返回事件实例 使用新操作符创建 有关详细信息,请参阅第节 了解定制事件的好地方,供新的flex/as3开发人员阅读
注意:链接指向Flex 4.6文档,但自定义事件部分不依赖于版本(对于Flex 3和以前的版本,只有mxml部分可能不同)您必须返回事件类的新构造函数,如:
return new ShopEvent(type,...); //in the clone() method;
clone()
方法通过在克隆中设置type属性和任何新属性来返回事件对象的克隆副本。通常,您可以定义clone()
方法返回使用新运算符创建的事件实例。您刚才是否根据错误消息提出了建议?我确信,我正在创建并传递ShopEvent的实例。您能否指出错误可能出现在哪一行?菜单[I]。addEventListener(ShopEvent.MENU_已选择,函数(e:ShopEvent):void{dispatchEvent(e);});这很简单,但对我来说很有用。我在clone()中所做的只是返回实例“this”。但是出现了一些问题,我的lister事件根本没有触发。(如果我创建了一个新实例并传递了新的intance(未克隆),则会触发。)我已经阅读了文档。这真的很尴尬,我必须创建一个新实例并复制所有属性。为什么会这样是这样实现的吗?如果杰克的答案是正确的,你应该接受他的答案,而不是你自己的答案。@MartyPitt我希望我的答案能对其他人有所帮助。是的,我已经接受了他的答案
return new ShopEvent(type,...); //in the clone() method;