Flex 4カスタムコンポーネントからカスタムイベントをディスパッチします
-
25-10-2019 - |
質問
これは質問に似ています ここ. 。カスタムイベント「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>
親カスタムコンポーネント。これは、上記のカスタムコンポーネントの親コンポーネントです。メニューセントされたイベントに耳を傾け、リスナーにイベントをルーティングするだけです。肉データタグを確認してください。イベント登録は適切に行われます。
ただし、エラーが発生しています
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="<" />
<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>
解決
カスタムイベントクラスのClone()メソッドを上書きする必要があります。伝播中にイベントを数回クローニングできます。
他のヒント
ジャックの答えは正しいです。 Flexドキュメントに記載されています。
サブクラスのイベントをオーバーライドする必要があります。clone()メソッド。 clone()メソッドは、型プロパティとクローン内の新しいプロパティを設定することにより、イベントオブジェクトのクローンコピーを返します。通常、Clone()メソッドを定義して、新しいオペレーターで作成されたイベントインスタンスを返します。
詳細については、お読みください イベントを操作します 下 イベントからサブクラスを作成します セクション
新しいFlex/AS3開発者が読むためのカスタムイベントを理解するのに適した場所 カスタムイベントを発送します
注:リンクはFlex 4.6ドキュメントを指していますが、カスタムイベントパーツはバージョンに依存していません(Flex 3および以前のバージョンではMXMLパーツのみが異なる場合があります)
次のようなイベントクラスの新しいコンストラクターを返す必要があります。
return new ShopEvent(type,...); //in the clone() method;
clone()
メソッドは、タイププロパティとクローン内の新しいプロパティを設定することにより、イベントオブジェクトのクローンコピーを返します。通常、あなたは定義します clone()
新しいオペレーターで作成されたイベントインスタンスを返す方法。
あなたが派遣しているイベントは、Type Flash.Events.Eventからのものであり、リスナーが予想しているイベントはType:com.events.shopeventからです。
これは単にエラーメッセージの意味です。