Flex - 父级不执行子级函数
非常感谢 www.Flextras.com 在过去几天里一直帮助我解决这个问题,我几乎已经明白了。我有一个 main.mxml、child.mxml 和 headermenu.mxml。我单击标题菜单上的一个按钮,将事件分派到 main.mxml,然后执行 child.mxml 中的方法。我知道这是有效的,因为我在 child.mxml 内部调用的函数中放置了一个 AlertDialog。 child.mxml 包含一个具有擦除() 的drawingArea 对象。当我直接从 child.xml 调用它时,它会执行,但是如果我将 DrawingArea.erase() 放在子级的父级 (main.mxml) 调用的函数内,则不会发生任何情况。
这是我的代码:
Telestrator.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.TelestratorHome" creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.effects.Fade;
import mx.events.ChildExistenceChangedEvent;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
import qnx.dialog.AlertDialog;
import qnx.events.QNXApplicationEvent;
import qnx.system.QNXApplication;
import views.TelestratorHome;
private var headerTimer:Timer = new Timer(5000,1);
[Bindable] private var headerMenu:HeaderMenu;
[Bindable] private var headerMenuDisplayed:Boolean = false;
private var tele:TelestratorHome;
private var alert2:AlertDialog = new AlertDialog();
protected function creationCompleteHandler(event:FlexEvent):void
{
QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_DOWN, onApplicationSwipeDown);
headerMenu = new HeaderMenu();
headerMenu.addEventListener(MouseEvent.CLICK, onHeaderMenuClick);
this.tele = new TelestratorHome();
this.tele.width = 100;
this.tele.height = 100;
this.tele.x = 10;
this.tele.y = 10;
this.addChild( tele );
headerMenu.addEventListener('parentDoSomething', onHeaderBarToldMeTo);
headerTimer.addEventListener(TimerEvent.TIMER, onHeaderMenuTimerEvent);
}
protected function onApplicationSwipeDown(event:QNXApplicationEvent) : void
{
showHeaderMenuPopup();
}
private function showHeaderMenuPopup() : void
{
if (!headerMenuDisplayed)
{
headerMenu.x = 0;
headerMenu.y = 0;
PopUpManager.addPopUp(headerMenu,this, false);
headerPopupEffectIn.end();
headerPopupEffectIn.play();
headerMenuDisplayed = true;
}
headerTimer.reset();
headerTimer.start();
}
private function onHeaderMenuTimerEvent(event:TimerEvent) : void
{
hideHeaderMenuPopup();
headerTimer.stop();
}
private function onHeaderMenuClick(event:MouseEvent) : void
{
hideHeaderMenuPopup();
}
private function hideHeaderMenuPopup() : void
{
headerPopupEffectOut.end();
headerPopupEffectOut.play();
headerPopupEffectOut.addEventListener(EffectEvent.EFFECT_END, headerMenuHidden);
}
private function headerMenuHidden(event:EffectEvent) : void
{
PopUpManager.removePopUp(headerMenu);
headerPopupEffectIn.removeEventListener(EffectEvent.EFFECT_END, headerMenuHidden);
headerMenuDisplayed = false;
}
protected function onHeaderBarToldMeTo(event:Event):void{
tele.eraseCanvas(event);
}
]]>
</fx:Script>
<fx:Declarations>
<s:Parallel id="headerPopupEffectIn" target="{headerMenu}">
<s:Move duration="250" yFrom="-75" xTo="0" yTo="0" easer="{sineEaser}" />
</s:Parallel>
<s:Parallel id="headerPopupEffectOut" target="{headerMenu}">
<s:Move duration="250" yFrom="0" xTo="0" yTo="-75" easer="{sineEaser}" />
</s:Parallel>
<s:Sine id="sineEaser" easeInFraction="0.2" />
</fx:Declarations>
</s:MobileApplication>
TelestratorHome.mxml
------------------
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
actionBarVisible="true" creationComplete="init()" overlayControls="false"
tabBarVisible="true" title="Telestrator">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:actionContent>
<s:Button label="Erase" click="drawingArea.erase(event)"/>
<s:Button id="saveBtn" label="Save Image" click="save()" visible="false"/>
</s:actionContent>
<s:titleContent>
<s:Button label="Take Photo" click="takeSnapshot()"/>
</s:titleContent>
<s:Panel id="p" top="1" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0">
<s:Panel id="imageViewer" top="-32" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0"/>
<s:Panel id="preview" top="-32" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0"/>
<DrawingArea xmlns="*" id="drawingArea" y="-32" width="100%" height="509"/>
</s:Panel>
<fx:Script>
<![CDATA[
import com.tinkerlog.WebCam;
import com.tinkerlog.util.Base64;
import flash.media.Camera;
import mx.core.UIComponent;
import mx.graphics.codec.JPEGEncoder;
import mx.graphics.codec.PNGEncoder;
import qnx.dialog.AlertDialog;
private var webCam:WebCam;
private var alert3:AlertDialog = new AlertDialog();
private function init():void {
webCam = new WebCam(1024, 600);
var ref:UIComponent = new UIComponent();
preview.removeAllElements();
preview.addElement(ref);
ref.addChild(webCam);
}
private function takeSnapshot():void {
imageViewer.visible = true;
preview.visible=false;
saveBtn.visible = true;
imageViewer.width = preview.width;
imageViewer.height = preview.height;
var uiComponent : UIComponent = new UIComponent();
uiComponent.width = webCam.width;
uiComponent.height = webCam.height;
var photoData:Bitmap = webCam.getSnapshot();
var photoBitmap:BitmapData = photoData.bitmapData;
uiComponent.addChild(photoData);
imageViewer.removeAllElements();
imageViewer.addElement(uiComponent);
}
private function deleteSnapshot():void {
imageViewer.removeAllElements();
}
public function save():void
{
var bd:BitmapData = new BitmapData(p.width, p.height);
bd.draw(this);
var ba:ByteArray = (new PNGEncoder()).encode(bd);
(new FileReference()).save(ba, "doodle.png");
}
public function eraseCanvas(event:Event):void{
drawingArea.erase(event);
}
]]>
</fx:Script>
</s:View>
HeaderMenu.mxml
--------------
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" borderVisible="false"
xmlns:s="library://ns.adobe.com/flex/spark" width="1024" height="75" xmlns:mx="library://ns.adobe.com/flex/mx" >
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import qnx.dialog.AlertDialog;
private var tele:Telestrator = new Telestrator();
private var alert:AlertDialog = new AlertDialog();
protected function btn_clickHandler(event:MouseEvent):void
{
// Figure out which button was pressed, and load appropriate view.
}
protected function onButtonInheaderbarClick(event:Event):void{
dispatchEvent(new Event('parentDoSomething'));
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:backgroundFill>
<s:SolidColor alpha="0.9" color="#000000" />
</s:backgroundFill>
<s:layout>
<s:HorizontalLayout horizontalAlign="right" verticalAlign="middle" paddingTop="5" paddingBottom="5" paddingRight="5" paddingLeft="5" gap="5"/>
</s:layout>
<s:Button id="btn_refresh" label="Refresh" height="60" fontSize="18" click="onButtonInheaderbarClick(event)"/>
<s:Label text="APPLICATION NAME" fontSize="32" styleName="FeedItemTitle" textAlign="center" width="100%" height="100%" verticalAlign="middle" />
<s:Button id="btn_about" label="About" height="60" fontSize="18" click="btn_clickHandler(event)"/>
</s:BorderContainer>
Many thanks to www.Flextras.com who has been helping me with this question the last couple of days, and I almost have it. I have a main.mxml, child.mxml and headermenu.mxml. I click a button on the headermenu that dispatches an event up to the main.mxml which then executes a method in child.mxml. I know this works because I put an AlertDialog in the function I'm calling inside of the child.mxml. The child.mxml contains a drawingArea object that has an erase(). When I call this directly from child.xml it executes, however if I put drawingArea.erase() inside of the function being called by child's parent (main.mxml) nothing happens.
Here is my code:
Telestrator.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.TelestratorHome" creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.effects.Fade;
import mx.events.ChildExistenceChangedEvent;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
import qnx.dialog.AlertDialog;
import qnx.events.QNXApplicationEvent;
import qnx.system.QNXApplication;
import views.TelestratorHome;
private var headerTimer:Timer = new Timer(5000,1);
[Bindable] private var headerMenu:HeaderMenu;
[Bindable] private var headerMenuDisplayed:Boolean = false;
private var tele:TelestratorHome;
private var alert2:AlertDialog = new AlertDialog();
protected function creationCompleteHandler(event:FlexEvent):void
{
QNXApplication.qnxApplication.addEventListener(QNXApplicationEvent.SWIPE_DOWN, onApplicationSwipeDown);
headerMenu = new HeaderMenu();
headerMenu.addEventListener(MouseEvent.CLICK, onHeaderMenuClick);
this.tele = new TelestratorHome();
this.tele.width = 100;
this.tele.height = 100;
this.tele.x = 10;
this.tele.y = 10;
this.addChild( tele );
headerMenu.addEventListener('parentDoSomething', onHeaderBarToldMeTo);
headerTimer.addEventListener(TimerEvent.TIMER, onHeaderMenuTimerEvent);
}
protected function onApplicationSwipeDown(event:QNXApplicationEvent) : void
{
showHeaderMenuPopup();
}
private function showHeaderMenuPopup() : void
{
if (!headerMenuDisplayed)
{
headerMenu.x = 0;
headerMenu.y = 0;
PopUpManager.addPopUp(headerMenu,this, false);
headerPopupEffectIn.end();
headerPopupEffectIn.play();
headerMenuDisplayed = true;
}
headerTimer.reset();
headerTimer.start();
}
private function onHeaderMenuTimerEvent(event:TimerEvent) : void
{
hideHeaderMenuPopup();
headerTimer.stop();
}
private function onHeaderMenuClick(event:MouseEvent) : void
{
hideHeaderMenuPopup();
}
private function hideHeaderMenuPopup() : void
{
headerPopupEffectOut.end();
headerPopupEffectOut.play();
headerPopupEffectOut.addEventListener(EffectEvent.EFFECT_END, headerMenuHidden);
}
private function headerMenuHidden(event:EffectEvent) : void
{
PopUpManager.removePopUp(headerMenu);
headerPopupEffectIn.removeEventListener(EffectEvent.EFFECT_END, headerMenuHidden);
headerMenuDisplayed = false;
}
protected function onHeaderBarToldMeTo(event:Event):void{
tele.eraseCanvas(event);
}
]]>
</fx:Script>
<fx:Declarations>
<s:Parallel id="headerPopupEffectIn" target="{headerMenu}">
<s:Move duration="250" yFrom="-75" xTo="0" yTo="0" easer="{sineEaser}" />
</s:Parallel>
<s:Parallel id="headerPopupEffectOut" target="{headerMenu}">
<s:Move duration="250" yFrom="0" xTo="0" yTo="-75" easer="{sineEaser}" />
</s:Parallel>
<s:Sine id="sineEaser" easeInFraction="0.2" />
</fx:Declarations>
</s:MobileApplication>
TelestratorHome.mxml
------------------
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
actionBarVisible="true" creationComplete="init()" overlayControls="false"
tabBarVisible="true" title="Telestrator">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:actionContent>
<s:Button label="Erase" click="drawingArea.erase(event)"/>
<s:Button id="saveBtn" label="Save Image" click="save()" visible="false"/>
</s:actionContent>
<s:titleContent>
<s:Button label="Take Photo" click="takeSnapshot()"/>
</s:titleContent>
<s:Panel id="p" top="1" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0">
<s:Panel id="imageViewer" top="-32" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0"/>
<s:Panel id="preview" top="-32" width="1024" height="600" backgroundAlpha="0.0" horizontalCenter="0"/>
<DrawingArea xmlns="*" id="drawingArea" y="-32" width="100%" height="509"/>
</s:Panel>
<fx:Script>
<![CDATA[
import com.tinkerlog.WebCam;
import com.tinkerlog.util.Base64;
import flash.media.Camera;
import mx.core.UIComponent;
import mx.graphics.codec.JPEGEncoder;
import mx.graphics.codec.PNGEncoder;
import qnx.dialog.AlertDialog;
private var webCam:WebCam;
private var alert3:AlertDialog = new AlertDialog();
private function init():void {
webCam = new WebCam(1024, 600);
var ref:UIComponent = new UIComponent();
preview.removeAllElements();
preview.addElement(ref);
ref.addChild(webCam);
}
private function takeSnapshot():void {
imageViewer.visible = true;
preview.visible=false;
saveBtn.visible = true;
imageViewer.width = preview.width;
imageViewer.height = preview.height;
var uiComponent : UIComponent = new UIComponent();
uiComponent.width = webCam.width;
uiComponent.height = webCam.height;
var photoData:Bitmap = webCam.getSnapshot();
var photoBitmap:BitmapData = photoData.bitmapData;
uiComponent.addChild(photoData);
imageViewer.removeAllElements();
imageViewer.addElement(uiComponent);
}
private function deleteSnapshot():void {
imageViewer.removeAllElements();
}
public function save():void
{
var bd:BitmapData = new BitmapData(p.width, p.height);
bd.draw(this);
var ba:ByteArray = (new PNGEncoder()).encode(bd);
(new FileReference()).save(ba, "doodle.png");
}
public function eraseCanvas(event:Event):void{
drawingArea.erase(event);
}
]]>
</fx:Script>
</s:View>
HeaderMenu.mxml
--------------
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" borderVisible="false"
xmlns:s="library://ns.adobe.com/flex/spark" width="1024" height="75" xmlns:mx="library://ns.adobe.com/flex/mx" >
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import qnx.dialog.AlertDialog;
private var tele:Telestrator = new Telestrator();
private var alert:AlertDialog = new AlertDialog();
protected function btn_clickHandler(event:MouseEvent):void
{
// Figure out which button was pressed, and load appropriate view.
}
protected function onButtonInheaderbarClick(event:Event):void{
dispatchEvent(new Event('parentDoSomething'));
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:backgroundFill>
<s:SolidColor alpha="0.9" color="#000000" />
</s:backgroundFill>
<s:layout>
<s:HorizontalLayout horizontalAlign="right" verticalAlign="middle" paddingTop="5" paddingBottom="5" paddingRight="5" paddingLeft="5" gap="5"/>
</s:layout>
<s:Button id="btn_refresh" label="Refresh" height="60" fontSize="18" click="onButtonInheaderbarClick(event)"/>
<s:Label text="APPLICATION NAME" fontSize="32" styleName="FeedItemTitle" textAlign="center" width="100%" height="100%" verticalAlign="middle" />
<s:Button id="btn_about" label="About" height="60" fontSize="18" click="btn_clickHandler(event)"/>
</s:BorderContainer>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,仍在查看它,但我看到的第一个错误是嵌套函数,这可能会导致范围问题,所以让我们从它开始,看看是否有帮助。
像这样修复您的 DrawingArea 类。
在 main.mxml 中执行此操作
OK, still looking it over but the first mistake I see is you nested function which could be causing scoping issues so lets start with that and see if that helps.
Fix your DrawingArea class like so.
In main.mxml do this