`
兩ting
  • 浏览: 75142 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

关于flex不能移除监听器总结

    博客分类:
  • flex
阅读更多

首先看我从网上转载了一篇文章:

<!------------

在flex中我们可以很方便的在mxml标签中使用事件名="函数名()"来给对象添加侦听..

像click="goUrl()"
可是当我们不需要该侦听的时候..
如果想使用
id.removeEventListener("click",goUrl)来删除侦听.
却发现怎么也remove不成功..
原来使用该方法给对象添加侦听时..
flex并不是直接使用我们指定的函数(goUrl),
而是先动态生成一个函数.
然后再使用该函数调用我们指定的函数..
所以我们使用id.removeEventListener("click",goUrl)当然就失败了...
正当ym的时候..记得之前使用过状态(state)来移除过这样的侦听..
马上试了下一下..
<mx:states>
  <mx:State name="statename">
    <mx:SetEventHandler target="{obj}" name="click"/>
  </mx:State>
</mx:states> 
运行了一下..果然成功了..
无耐之前只好把swf反编译一下...终于在代码里看到了
一个叫"__obj_click"的函数..
猜想这个应该就是由flex动态添加的函数..于是试了一下...
obj.removeEventListener("click",this["__obj_click"]); 
//这里需要注意..为什么不直接使用__obj_click
而使用this["__obj_click"],
因为当flex编译时..__obj_click 这个函数还不存在,直接调用会出错..所以取巧一下..
保存运行..侦听成功删除...猜想正确...
分析一下该函数的规律..
第一部份是"__"
第二部份是对象ID
第三部份是"_"
第四部份是事件名
相应的
mouseOver事件就是__obj_mouseOver
mouseDown事件就是__obj_mouseDown

-------------!>

 

在实际运用中,我们可能为某个组件或容器添加监听

xx(Id).addEventListener(xxxEvent,fun)

又要在AS代码中用获取组件或容器的ID来移除监听

xx(Id).removeEventListener(xxxEvent,fun);此时不能移除该监听改怎么办呢?


今天在开发的时候用到了一种比较简单和实用的办法就是,在上面的监听事件执行方法fun中用判断

一个变量的值来控制代码执行,比如加一个flg:Boolean的开关,将要监听的代码放到if(flg){}里面,用

不到监听时,但现在又不能移除监听,这时就可以将flg设置为false不然监听事件的方法执行任何逻辑

代码。这样虽然没有根本移除监听,但对要经常在一个容器或组件上反复使用和取消监听的菜鸟是个很

不错的解决方法!!!

 

我们继续用代码来实例为在mxml中的组件不能用xx(Id).removeEventListener(xxxEvent,fun)移除

和哪些情况可以移除,请阅读下面实例:(自定义监听事件参数,和移除监听)

我们知道FLEX添加监听事件,会经常使用到,但是常见的方法,并不能自定义参数。我收集到一个非常好的方法。可以在监听的时候,添加自己喜欢的参数。好吧,我们开始第一个

 

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.                xmlns:s="library://ns.adobe.com/flex/spark"   
  4.                xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">  
  5.       
  6.     <fx:Script>  
  7.         <![CDATA[ 
  8.             import mx.controls.Alert; 
  9.             public var count:int=0; 
  10.             protected function button1_clickHandler(event:MouseEvent):void 
  11.             { 
  12.                 bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void 
  13.                 { 
  14.                     clickPar(event,20,30); 
  15.                 }); 
  16.             } 
  17.             protected function clickPar(event:MouseEvent,x:int,y:int):void 
  18.             { 
  19.                  
  20.                 count++; 
  21.                 ta.text+="被调用了"+count+"次"+"x:"+x+"y:"+y+"\n"; 
  22.             } 
  23.  
  24.  
  25.              
  26.  
  27.         ]]>  
  28.     </fx:Script>  
  29.       
  30.     <fx:Declarations>  
  31.         <!-- 将非可视元素(例如服务、值对象)放在此处 -->  
  32.           
  33.     </fx:Declarations>  
  34.     <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>  
  35.     <s:Button x="63" y="97" label="按钮2" id="bt2"/>  
  36.     <s:TextArea x="217" y="32" id="ta"/>  
  37.       
  38. </s:Application>  

点击按钮1,为按钮2,添加相应的监听事件,点击一次按钮一,将会增加一次对按钮2的监听。这样我们就可以实现监听事件的时候,传递相关参数。问题来了,我们现在需要移除监听。好吧,我们继续,按照我们常规的做法,就是把这个函数再写一遍就是了。
[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.                xmlns:s="library://ns.adobe.com/flex/spark"   
  4.                xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">  
  5.       
  6.     <fx:Script>  
  7.         <![CDATA[ 
  8.             import mx.controls.Alert; 
  9.             public var count:int=0; 
  10.             protected function button1_clickHandler(event:MouseEvent):void 
  11.             { 
  12.                 bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void 
  13.                 { 
  14.                     clickPar(event,20,30); 
  15.                 }); 
  16.             } 
  17.             protected function clickPar(event:MouseEvent,x:int,y:int):void 
  18.             { 
  19.                  
  20.                 count++; 
  21.                 ta.text+="被调用了"+count+"次"+"x:"+x+"y:"+y+"\n"; 
  22.             } 
  23.             protected function button3_clickHandler(event:MouseEvent):void 
  24.             { 
  25.                 bt2.removeEventListener(MouseEvent.CLICK,function(event:MouseEvent):void 
  26.                 { 
  27.                     clickPar(event,20,30); 
  28.                                  }); 
  29.             } 
  30.  
  31.              
  32.  
  33.         ]]>  
  34.     </fx:Script>  
  35.       
  36.     <fx:Declarations>  
  37.         <!-- 将非可视元素(例如服务、值对象)放在此处 -->  
  38.           
  39.     </fx:Declarations>  
  40.     <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>  
  41.     <s:Button x="63" y="97" label="按钮2" id="bt2"/>  
  42.     <s:TextArea x="217" y="32" id="ta"/>  
  43.     <s:Button x="63" y="155" label="按钮3" click="button3_clickHandler(event)"/>  
  44. </s:Application>  
我们点击按钮三的时候,事实并非所想,难道这是一个bug,还是怎么回事?开始骂Adobe,设计的什么玩意。

 

其实function(event:MouseEvent):void
{
clickPar(event,20,30);
}

这是一个匿名函数,虽然写的是一模一样,但是函数地址是不一样的,所以说,移除的不是你添加的,这句话你明白了吗?我似乎听见,都在说,small case。

解铃还须系铃人,我们把那个监听的函数给记住,然后不就可以了吗!对。这个匿名函数,怎么能得到他呢。当然我们可以查一下帮助文档,arguments 出现在我们面前,为什么我会知道这个东西呢?当然,我写这篇文章之前,我都从网络上搜索好了,实现方法是什么,所以知道该查什么。

 

callee

property

 

public var callee:Function

 

Language Version:  ActionScript 3.0
Runtime Versions:  AIR 1.0, Flash Player 8, Flash Lite 4

 

 

A reference to the currently executing function.


这是他的原话,意思是一个对当前函数的引用。秀一下英语,比较难的时候,我都在google翻译过来,然后再去理解。

 

下面稍微修改一下,就可以移除了。

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.                xmlns:s="library://ns.adobe.com/flex/spark"   
  4.                xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">  
  5.       
  6.     <fx:Script>  
  7.         <![CDATA[ 
  8.             import mx.controls.Alert; 
  9.             public var count:int=0; 
  10.             public var ft:Function; 
  11.             protected function button1_clickHandler(event:MouseEvent):void 
  12.             { 
  13.                  
  14.                 bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void 
  15.                 { 
  16.                     clickPar(event,20,30,arguments.callee); 
  17.                 }); 
  18.             } 
  19.             protected function clickPar(event:MouseEvent,x:int,y:int,fn:Function):void 
  20.             { 
  21.                 ft=fn; 
  22.                 count++; 
  23.                 ta.text+="被调用了"+count; 
  24.             } 
  25.              
  26.              
  27.             protected function button3_clickHandler(event:MouseEvent):void 
  28.             { 
  29.                  
  30.                 bt2.removeEventListener(MouseEvent.CLICK,ft); 
  31.             } 
  32.              
  33.         ]]>  
  34.     </fx:Script>  
  35.       
  36.     <fx:Declarations>  
  37.         <!-- 将非可视元素(例如服务、值对象)放在此处 -->  
  38.           
  39.     </fx:Declarations>  
  40.     <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>  
  41.     <s:Button x="63" y="97" label="按钮2" id="bt2"/>  
  42.     <s:TextArea x="217" y="32" id="ta"/>  
  43.     <s:Button x="63" y="155" label="按钮3" click="button3_clickHandler(event)"/>  
  44.       
  45. </s:Application>  

 

我总感觉,Flex与JS有太多的相似性,当我不熟悉Flex的时候,我就向JS想,看看能不能有什么突破点没。

 

 

 

 

分享到:
评论
1 楼 jinx3166 2013-09-02  
受益良多!

相关推荐

Global site tag (gtag.js) - Google Analytics