0

奇妙な問題があります!関数を呼び出して FileReference オブジェクトのイベント リスナーを削除しようとしていますが、削除されていないようで、理由がわかりません。

コードは次のとおりです。

private function clearFileUploadListeners(file:FileReference, index:String):void {
    var dispatchEvent:Function = function(event:Event):void {
        dispatch(event.type, event, index);
    };

    file.removeEventListener(Event.COMPLETE, dispatchEvent);
    var bool:Boolean = file.hasEventListener(Event.COMPLETE);
    if (bool)
        trace("ERROR");
}

このコードを実行すると、実際にトレースが発生します。すぐ上の eventListener を削除しようとしたときに、このブール値が true を返す理由がわかりません! 奇妙なエラーのように見えるので、おそらく本当にばかげたことをしていると思います。

誰かがこの問題について私を助けてくれることを願っています。

編集:

リスナーを追加するときに、dispatchEvent関数が別の関数内で定義されているという事実に関係していると思います:

private function upload(file:FileReference, index:String):void {
    var dispatchEvent:Function = function(event:Event):void {
        dispatch(event.type, event, index);
    };

    file.addEventListener(Event.COMPLETE, dispatchEvent);
}

問題は、リスナーからこの「インデックス」変数にアクセスする必要があることです。各ファイルには独自のインデックスがあり、追跡するために各イベント クラスを拡張する必要がある場合は負担になるため、グローバル変数として設定できません。インデックス (Event、ProgressEvent、..) の 誰かがこれについて私を助けてくれることを願っています。

EDIT2:

実際に一時的な解決策を見つけましたが、それが最善かどうかはわかりません! removeListener メソッドを実際には upload メソッド内に配置しましたが、変数にしました。AS3 では動的オブジェクトが許可されているため、このメソッドをオブジェクトの 1 つにアタッチし、必要に応じてメソッドへの参照を呼び出すだけです。イベントは実際に削除されます。これは良い解決策ですか?

どうもありがとう、ルディ

4

2 に答える 2

1

そうです、別の関数内で関数を定義し、それを使用してイベントを処理するという事実に関係しています。

関数が呼び出されるたびにupload、新しいクロージャーが作成され、それへの参照が変数に割り当てられ、クラスdispatchEventに渡されます。addEventListenerしたがって、 が呼び出されるたびに、 への呼び出しでupload新しい異なるクロージャが使用されaddEventListenerます。同様に、clearFileUploadListeners関数では、呼び出しごとに新しいクロージャーが作成されます (毎回同じコードが含まれますが、同じ関数オブジェクトではありません)。removeEventListener指定されたコールバックが指定されたイベントのイベント リスナーとして追加されていない場合、への呼び出しは何もしません。

問題を解決するには、関数に渡すクロージャーへの参照を保存する必要がありaddEventListenerます。このようにして、後で削除する必要があるときに追加された同じクロージャーへの参照を取得できますclearFileUploadListeners

次のコードの行に沿って何かを試すことができます (テストされていません)。

import flash.utils.Dictionary;

var callbackRegistry:* = new Dictionary();


private function upload(file:FileReference, index:String):void {
    var dispatchEvent:Function = generateFileUploadCompleteCallback();

    callbackRegistry[file] = dispatchEvent;

    file.addEventListener(Event.COMPLETE, dispatchEvent);
}

private function clearFileUploadListeners(file:FileReference, index:String):void {
    var dispatchEvent:Function = callbackRegistry[file];
    callbackRegistry[file] = null;

    file.removeEventListener(Event.COMPLETE, dispatchEvent);

    var bool:Boolean = file.hasEventListener(Event.COMPLETE);
    if (bool)
        trace("ERROR");
    else
        trace("YAY, ALL OK!");
}

private function generateFileUploadCompleteCallback(index:String):Function {
    return function(event:Event):void {
        dispatch(event.type, event, index);
    };
}
于 2010-06-16T22:42:50.413 に答える