2008-10-08 3 views
6

मैं एक पुन: प्रयोज्य बटन चाहता हूं जिसे बाहरी स्रोत द्वारा निर्धारित कई अलग-अलग कॉलबैक में से एक के लिए पंजीकृत किया जा सकता है। जब एक नया कॉलबैक सेट किया जाता है, तो मैं पुराने को हटाना चाहता हूं। मैं किसी भी समय कॉलबैक को बाहरी रूप से साफ़ करने में सक्षम होना चाहता हूं।क्या ऑब्जेक्ट से अज्ञात ईवेंट श्रोताओं को हटाने का कोई तरीका है?

public function registerButtonCallback(function:Function):void 
{ 
    clearButtonCallback(); 

    button.addEventListener(MouseEvent.CLICK, function, false, 0, true); 
} 

public function clearButtonCallback():void 
{ 
    if (button.hasEventListener(MouseEvent.CLICK) == true) 
    { 
    // do something to remove that listener 
    } 
} 

मैंने देखा है यहाँ पर सुझाव कॉलबैक के भीतर "arguments.callee" का उपयोग करने, लेकिन मैं कॉलबैक से बंधा है कि कार्यक्षमता है नहीं करना चाहते - उदाहरण के लिए, मैं करने के लिए सक्षम होने के लिए चाहते हो सकता है दो बार बटन पर क्लिक करें।

सुझाव?

उत्तर

8

मैं यह मानते हुए कि आप किसी भी समय में केवल एक कॉलबैक समारोह चाहते हैं। अगर ऐसा तेह मामले तो क्यों बटन जो अपने आप में एक समारोह को फोन किया और उस समारोह settable हो है पर क्लिक करें घटना के साथ जुड़े एक भी कॉलबैक फ़ंक्शन नहीं ...

<mx:Button click="doCallback()" .../> 

public var onClickFunction:Function = null; 
private function doCallback():void 
{ 
    if (onClickFunction != null) 
    { 
     onClickFunction(); // optionally you can pass some parameters in here if you match the signature of your callback 
    } 
} 

आपके नियंत्रण से एक उपभोक्ता जो अपने बटन घरों उपयुक्त फ़ंक्शन के साथ ऑनक्लिक फ़ंक्शन सेट करेगा। असल में आप जितनी बार चाहें उतनी बार इसे सेट कर सकते हैं।

आप एक कदम आगे जाने के लिए आप AS3 बटन वर्ग उपवर्ग और इसके अंदर यह सब लपेट सकता है चाहता है तो।

+0

पकड़ लिया। आप जानते हैं, मुझे लगता है कि मैंने ऐसा करना शुरू कर दिया और किसी कारण से इसके खिलाफ फैसला किया जो मुझे याद नहीं है। किसी भी तरह से, आपकी धारणा सही है और मेरे द्वारा किए गए कार्यों को करने का यह एक अच्छा तरीका है। धन्यवाद। –

+0

बढ़िया, खुश मैं मदद कर सकता था। यदि आप इसे उत्तर के रूप में चिह्नित करते हैं तो मुझे कुछ प्रतिनिधि बिंदु भी मिलेंगे :-) – Simon

3

स्टोर एक आधार के रूप में श्रोता। जब कोई अन्य ईवेंट जोड़ा जाता है, तो यह देखने के लिए जांचें कि श्रोता मौजूद है या नहीं, और यदि यह करता है, तो हटाएं IventListener को कॉल करें।

वैकल्पिक रूप से, आप बटन के addEventListener विधि ओवरराइड। जब addEventListener कहा जाता है, तो उसे किसी ऑब्जेक्ट ऑब्जेक्ट में ईवेंट में जोड़ने से पहले बंद करें। जब addEventListener फिर से कहा जाता है, इसे हटाने:


var listeners:Dictionary = new Dictionary();

override public function addEventListener(type : String, listener : Function, useCapture : Boolean = false, priority : int = 0, useWeakReference : Boolean = false) : void {

if(listeners[ type ]) { 

    if(listeners[ type ] [ useCapture ] { 

     //snip... etc: check for existence of the listener 

     removeEventListener(type, listeners[ type ] [ useCapture ], useCapture); 

     listeners[ type ] [ useCapture ] = null; 

     //clean up: if no listeners of this type exist, remove the dictionary key for the type, etc... 

    } 

    } 

    listeners[ type ] [ useCapture ] = listener; 

    super.addEventListener(type, listener, useCapture, priority, useWeakReference); 

}; 

+0

उन विकल्पों में से कोई भी नहीं जो प्रश्न पूछ रहा है, जो किसी मौजूदा EventDispatcher ऑब्जेक्ट से UNKOWN ईवेंट श्रोता को पुनर्प्राप्त करना है। ऑब्जेक्ट में जोड़े जाने से पहले ये विधियां सिर्फ एक ज्ञात श्रोता संग्रहित कर रही हैं। यदि श्रोता को ऑब्जेक्ट में जोड़े जाने से पहले ज्ञात और संग्रहीत नहीं किया जाता है, तो बाद में इसे पुनर्प्राप्त करने का कोई तरीका नहीं है। – Triynko

+3

लेकिन वे अज्ञात घटना श्रोताओं को ज्ञात करने के तरीकों की पेशकश करते हैं जो समस्या से संपर्क करने का एक और तरीका है। – voidstate

1

कुछ मैं एक गतिशील वैश्विक वर्ग का उपयोग करें और श्रोता समारोह इनलाइन करने के लिए एक त्वरित संदर्भ जोड़ने है क्या करना चाहते। यह माना जाता है कि आप addEventListener विधि में श्रोता समारोह को पसंद करते हैं जैसे मैं करता हूं। इस तरह, आप addEventListener :) अंदर removeEventListener का उपयोग

इस आजमाएँ कर सकते हैं:

package { 

import flash.display.Sprite; 
import flash.events.Event; 
import flash.text.TextField; 

[SWF(width="750", height="400", backgroundColor="0xcdcdcd")] 
public class TestProject extends Sprite 
{ 
    public function TestProject() 
    { 
     addEventListener(Event.ADDED_TO_STAGE, Global['addStageEvent'] = function():void { 
      var i:uint = 0; 
      //How about an eventlistener inside an eventListener? 
      addEventListener(Event.ENTER_FRAME, Global['someEvent'] = function():void { 
       //Let's make some text fields 
       var t:TextField = new TextField(); 
        t.text = String(i); 
        t.x = stage.stageWidth*Math.random(); 
        t.y = stage.stageHeight*Math.random(); 
       addChild(t); 
       i++; 
       trace(i); 
       //How many text fields to we want? 
       if(i >= 50) { 
        //Time to stop making textFields 
        removeEventListener(Event.ENTER_FRAME, Global['someEvent']); 
        //make sure we don't have any event listeners 
        trace("hasEventListener(Event.ENTER_FRAME) = "+hasEventListener(Event.ENTER_FRAME));  
       } 
      }); 

      //Get rid of the listener 
      removeEventListener(Event.ADDED_TO_STAGE, Global['addStageEvent']); 
      trace('hasEventListener(Event.ADDED_TO_STAGE) = '+hasEventListener(Event.ADDED_TO_STAGE)); 

     }); 
    } 

} 

}

// looky यहाँ! यह महत्वपूर्ण बिट गतिशील वर्ग वैश्विक {}

गुप्त गतिशील वर्ग वैश्विक है। इसके साथ आप रनटाइम पर गतिशील रूप से गुण जोड़ सकते हैं।

4

नहीं, आप इसे हटाने के लिए आदेश में श्रोता के लिए एक संदर्भ पकड़ की जरूरत है। जब तक आप श्रोता फ़ंक्शन को पहले से संदर्भित नहीं करते हैं, तब तक कोई Evented सार्वजनिक विधि किसी EventDispatcher से ऐसे संदर्भ को पुनर्प्राप्त करने के लिए उपलब्ध नहीं है।

addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
dispatchEvent(event:Event):Boolean 
hasEventListener(type:String):Boolean 
removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
willTrigger(type:String):Boolean 

आप देख सकते हैं, वहाँ घटना का एक प्रकार एक श्रोता पंजीकृत या उसके माता-पिता में से एक है, एक श्रोता पंजीकृत है, लेकिन उन तरीकों में से कोई भी वास्तव में पंजीकृत श्रोताओं की एक सूची प्रदान कि क्या आप यह बताने के लिए दो तरीके हैं ।

अब इस तरह के बेकार एपीआई लिखने के लिए एडोब को परेशान करें।असल में, वे आपको "प्रवाह" घटना प्रवाह बदलने के बारे में जानने की क्षमता देते हैं, लेकिन वे आपको उस जानकारी के साथ कुछ भी करने का कोई तरीका नहीं देते हैं!

2

मैं एक उपवर्ग उस उद्देश्य के लिए EventCurb बुलाया लिखा, मेरे blog यहाँ देख सकते हैं या पेस्ट नीचे।

package 
{ 
    import flash.events.EventDispatcher; 
    import flash.utils.Dictionary; 
    /** 
    * ... 
    * @author Thomas James Thorstensson 
    * @version 1.0.1 
    */ 
    public class EventCurb extends EventDispatcher 
    { 
     private static var instance:EventCurb= new EventCurb(); 
     private var objDict:Dictionary = new Dictionary(true); 
     private var _listener:Function; 
     private var objArr:Array; 
     private var obj:Object; 

     public function EventCurb() { 
     if(instance) throw new Error("Singleton and can only be accessed through Singleton.getInstance()"); 
     } 

     public static function getInstance():EventCurb { 
     return instance; 
     } 

     override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
     { 
     super.addEventListener(type, listener, useCapture, priority, useWeakReference); 
     } 

     override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
     { 
     super.removeEventListener(type, listener, useCapture); 
     } 

     public function addListener(o:EventDispatcher, type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { 
     // the object as key for an array of its event types 
     if (objDict[o] == null) objArr = objDict[o] = []; 
     for (var i:int = 0; i < objArr.length; i++) { 
      if (objArr[i].type == type) 
      trace ("_______object already has this listener not adding!") 
      return 
     } 
     obj = { type:type, listener:listener } 
     objArr.push(obj); 
     o.addEventListener(type, listener, useCapture, priority, useWeakReference); 
     } 

     public function removeListener(o:EventDispatcher, type:String, listener:Function, useCapture:Boolean = false):void { 
     // if the object has listeners (ie exists in dictionary) 
     if (objDict[o] as Array !== null) { 
      var tmpArr:Array = []; 
      tmpArr = objDict[o] as Array; 
      for (var i:int = 0; i < tmpArr.length; i++) { 
       if (tmpArr[i].type == type) objArr.splice(i); 
      } 

      o.removeEventListener(type, listener, useCapture); 
      if (tmpArr.length == 0) { 
       delete objDict[o] 
      } 
     }else { 
      trace("_______object has no listeners"); 
     } 
     } 

     /** 
     * If object has listeners, returns an Array which can be accessed 
     * as array[index].type,array[index].listeners 
     * @param o 
     * @return Array 
     */ 
     public function getListeners(o:EventDispatcher):Array{ 
     if (objDict[o] as Array !== null) { 
      var tmpArr:Array = []; 
      tmpArr = objDict[o] as Array; 
      // forget trying to trace out the function name we use the function literal... 
      for (var i:int = 0; i < tmpArr.length; i++) { 
       trace("_______object " + o + " has event types: " + tmpArr[i].type +" with listener: " + tmpArr[i].listener); 
      } 
      return tmpArr 

     }else { 
      trace("_______object has no listeners"); 
      return null 
     } 

     } 

     public function removeAllListeners(o:EventDispatcher, cap:Boolean = false):void { 
     if (objDict[o] as Array !== null) { 
      var tmpArr:Array = []; 
      tmpArr = objDict[o] as Array; 
      for (var i:int = 0; i < tmpArr.length; i++) { 
       o.removeEventListener(tmpArr[i].type, tmpArr[i].listener, cap); 
      } 
      for (var p:int = 0; p < tmpArr.length; p++) { 
       objArr.splice(p); 
      } 

      if (tmpArr.length == 0) { 
       delete objDict[o] 
      } 
     }else { 
      trace("_______object has no listeners"); 
     } 
     } 
    } 
} 
0
private function callFunction(function:Function):void 
{ 
    checkObject(); 
    obj.addEventListener(MouseEvent.CLICK,function); 
} 

private function checkObject():void 
{ 
    if(obj.hasEventListener(MouseEvent.CLICK)) 
    { 
     //here remove that objects 
    } 
} 
0

निम्नलिखित अज्ञात घटना श्रोताओं को दूर करने के मौलिक समस्या का समाधान नहीं करता है, लेकिन आपको क्या चाहिए अज्ञात सहित सभी माउस से संबंधित घटनाओं, अक्षम करने जाता है, बस का उपयोग करें: mouseEnabled = पर झूठे अपने घटना लक्ष्य

अधिक अच्छा यहाँ सामग्री: http://www.thoughtprocessinteractive.com/blog/the-power-and-genius-of-mousechildren-and-mouseenabled