拦截EventListener ActionScript

时间:2013-01-25 13:24:25

标签: actionscript-3 event-handling

我正在尝试扩展Button类并通过以下方法删除默认的EventListener:

removeEventListener(MouseEvent.CLICK, clickHandler);

然后添加如下内容:

    protected function _clickHandler(event:MouseEvent):void{
        Alert.show("Are you sure about this operation", "Alert", 3, this, execute);
        function execute(e:CloseEvent):void{
            if(e.detail == Alert.YES)
                super.clickHandler(event);
        }
    } 

这样,我将有一个默认组件,它将触发带有YES或NO选项的消息警报,并防止我必须在触发服务器的每个按钮上写入该组件。不幸的是,它不会那样工作。

  1. 尝试删除默认函数并添加我在侦听器上写的那个;
  2. 直接尝试覆盖clickHandler,也不起作用;

  3. 编辑:这就是我想要的:当用户点击一个将在我的应用程序中进行服务调用的按钮时,我总是弹出一个窗口让他告诉我他是否确定。我想要的是为此构建一个自动组件,如下所示:

    package screen{
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    import mx.controls.Alert;
    import mx.controls.Button;
    import mx.events.CloseEvent;
    
    public class CommonButton extends Button{
        public function CommonButton(){
            super();
            //removeEventListener(MouseEvent.CLICK, clickHandler)
            //addEventListener(MouseEvent.CLICK, clickHandler);
            addEventListener(KeyboardEvent.KEY_DOWN, function (e:KeyboardEvent):void{
                if(e.altKey == Keyboard.ENTER)
                    dispatchEvent(new MouseEvent(MouseEvent.CLICK));
            });
        }
    
        private var _saveEvent:MouseEvent;
        override protected function clickHandler(event:MouseEvent):void{
            _saveEvent = event;
            event.stopImmediatePropagation();
            Alert.show("Are you sure about this operation", "Alert", 3, this, execute);         
        } 
    
        private function execute(e:CloseEvent):void{
            if(e.detail == Alert.YES)
                super.clickHandler(_saveEvent);
        }
    }
    }
    

    然后:

        <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            private function test():void{
                //if the user clicked No, this method will never be called.
                Alert.show("You clicked YES");
            }
        ]]>
    </mx:Script>
    <screen:CommonButton click="test()" /> 
    

    使用解决方案进行最终编辑:

    package screen{
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    import mx.controls.Alert;
    import mx.controls.Button;
    import mx.events.CloseEvent;
    
    public class CommonButton extends Button{
        public function CommonButton(){
            super();
            addEventListener(KeyboardEvent.KEY_DOWN, function (e:KeyboardEvent):void{
                if(e.altKey == Keyboard.ENTER)
                    dispatchEvent(new MouseEvent(MouseEvent.CLICK));
            });
        }
    
        private var _stopProp:Boolean = true;
        override protected function clickHandler(event:MouseEvent):void{
            if(_stopProp){
                event.stopImmediatePropagation()
                Alert.show("Are you sure about this operation", "Alert", 3, this, execute);
            }else
                _stopProp = true;
    
        } 
    
        private function execute(e:CloseEvent):void{
            if(e.detail == Alert.YES){
                _stopProp = false;
                dispatchEvent(new MouseEvent(MouseEvent.CLICK));
            }
        }
    }
    

    }

2 个答案:

答案 0 :(得分:2)

为什么甚至打扰这个?只需将自定义事件处理程序添加到扩展组件,并允许正常事件处理程序触发。您可以在同一事件中注册多个处理程序。我认为这是一个问题的唯一原因是,如果你将它作为一个库发布,并希望阻止用户自己附加一个点击处理程序,但你不是。您根本不需要删除或停止默认的点击处理程序。

编辑:以下是提问者想要在这里发生的事情的一个例子。

public class AButton extends Button
{
    private var stopProp:Boolean = true;

    public function AButton()
    {
        super();
        this.addEventListener(MouseEvent.CLICK,this.clickHandlers);
    }

    private function clickHandlers( e:MouseEvent ):void{
        if ( stopProp ) {
            e.stopImmediatePropagation();

            trace( "clicked in button" );
            Alert.show( "Continue with event", "Warning!", Alert.YES|Alert.NO, null, this.closeHandler  );
        }
    }

    private function closeHandler( e:CloseEvent ):void {
        if ( e.detail == Alert.YES ) {
            this.stopProp = false;
            this.dispatchEvent( new MouseEvent( MouseEvent.CLICK ) );
            this.stopProp = true;
        }
    }
}

如果stopProp属性为true,那将阻止事件继续进行。然后它会提示用户。如果用户选择“是”,则会将stopProp设置为false,从按钮重新分配单击事件,并在下次将stopProp重置为false。如果他们选择“否”,则没有任何反应。

我制作了一个快速原型来测试它,它肯定有效。

答案 1 :(得分:0)

使用Event类的stopImmediatePropagation()方法。

protected function _clickHandler(event:MouseEvent):void{
    event.stopImmediatePropagation();

    Alert.show("Are you sure about this operation", "Alert", 3, this, execute);
    function execute(e:CloseEvent):void{
        if(e.detail == Alert.YES)
            super.clickHandler(event);
    }
}