开发者

Flex - parent not executing child's function

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'));  
                }
            ]]>
        开发者_如何学C</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>


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.

package{
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.FileReference;
    import flash.utils.ByteArray;

    import mx.core.UIComponent;
    import mx.events.FlexEvent;
    import mx.graphics.codec.PNGEncoder;

    public class DrawingArea extends UIComponent{
        private var isDrawing:Boolean = false;
        private var x1:int;
        private var y1:int;
        private var x2:int;
        private var y2:int;

        public var drawColor:uint = 0x000000;

        public function DrawingArea(){
            this.super();
            this.addEventListener(Event.ADDED_TO_STAGE,        this.erase );
            this.addEventListener(MouseEvent.MOUSE_DOWN,       this.mouseDown);
            this.addEventListener(MouseEvent.MOUSE_MOVE,       this.mouseMove);
            this.addEventListener(MouseEvent.MOUSE_UP,         this.mouseUp);
        }
        private function mouseDown( e:MouseEvent ):void{
          this.x1 = mouseX;
          this.y1 = mouseY;
          this.isDrawing = true;
        }
        private function mouseMove(e:MouseEvent ):void{
                if (!event.buttonDown){
                    this.isDrawing = false;
                }
                this.x2 = mouseX;
                this.y2 = mouseY;
                if (this.isDrawing){
                    this.graphics.lineStyle(2, this.drawColor);
                    this.graphics.moveTo(this.x1, this.y1);
                    this.graphics.lineTo(this.x2, this.y2);
                    this.x1 = this.x2;
                    this.y1 = this.y2;
                }
        }
        private function mouseUp( e:MouseEvent ):void{
          this.isDrawing = false;
        }
        public function erase( e:Event ):void{
            this.graphics.clear();
            this.graphics.beginFill(0xffffff, 0.00001);
            this.graphics.drawRect(0, 0, this.width, this.height);
            this.graphics.endFill();
        }
    }
}

In main.mxml do this

        private var child:Child;
        function init(){
          this.child =  = new Child();
          this.child.width = 100;
          this.child.height = 100;
          this.child.x = 10;
          this.child.y = 10;
          this.addChild( child );
          headerMenu.addEventListener('parentDoSomething', onHeaderBarToldMeTo);
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜