Существует ли способ удалить неизвестных слушателей события из объектов?

Я думаю, что trap является лучшим решением для этого

function interrupt(){

    local dir=$1
    [ -e ${dir} ] && rm -rf ${dir}
    exit 128
}
TMP_DIR=$(mktemp -d /tmp/entrypoint.XXXX)
trap "interrupt ${TMP_DIR}" SIGINT SIGTERM
trap "rm -rf ${TMP_DIR}" EXIT

set -ex
{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > ${TMP_DIR}/mysqld-init.sql

exec $@ --init-file="${TMP_DIR}/mysqld-init.sql"
6
задан Tim Cooper 1 September 2011 в 22:54
поделиться

5 ответов

Я предполагаю, что Вы хотите только одну функцию обратного вызова в любой момент времени. Если это так, затем, почему бы не отдельная функция обратного вызова, связанная с событием щелчка на кнопке, которая самой вызвала функцию и имеет ту функцию быть устанавливаемой...

<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
    }
}

Потребитель Вашего управления, которое содержит Вашу кнопку, установил бы onClickFunction с соответствующей функцией. На самом деле Вы могли устанавливать его так часто, как Вам понравилось.

Если бы Вы хотели пойти один шаг вперед, то Вы могли бы разделить класс Кнопки AS3 на подклассы и перенести всю эту внутреннюю часть он.

8
ответ дан 8 December 2019 в 13:03
поделиться

Что-то, что мне нравится делать, использовать динамический Глобальный класс и добавить справочник к встроенной функции слушателя. Это предполагает, что Вам нравится сделать, чтобы слушатель функционировал в addEventListener методе как, я делаю. Таким образом, можно использовать removeEventListener в addEventListener :)

Испытайте это:

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 здесь! Это - важный разрядный динамический класс, Глобальный {}

Секрет является динамическим Глобальным классом. С этим можно динамично включить свойства во времени выполнения.

1
ответ дан 8 December 2019 в 13:03
поделиться

Сохраните слушателя как опору. Когда другое событие добавляется, проверьте, чтобы видеть, существует ли слушатель, и если оно делает, назовите removeEventListener.

С другой стороны, переопределите 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 );

};

3
ответ дан 8 December 2019 в 13:03
поделиться

Нет. Вам нужно сохранить ссылку на слушателя, чтобы удалить его. Если вы заранее не сохраните ссылку на функцию прослушивателя, не существует документированного общедоступного метода, доступного для получения такой ссылки из 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 

Как вы можете видеть, есть два метода, чтобы сообщить вам, имеет ли тип события зарегистрированный слушатель или один из его родителей зарегистрировал слушателя, но ни один из этих методов на самом деле не возвращает список зарегистрированных слушателей.

Теперь, пожалуйста, преследуйте Adobe за написание такого бесполезного API. По сути, они дают вам возможность узнать, "изменился ли" поток событий, но они не дают вам возможности что-либо сделать с этой информацией!

4
ответ дан 8 December 2019 в 13:03
поделиться

Для этой цели я написал подкласс под названием EventCurb, см. Мой блог здесь или вставьте ниже.

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");
         }
      }
   }
}
2
ответ дан 8 December 2019 в 13:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: