2011-02-08 5 views
4

これは私を狂ってしまいます。 removeEventListenersが機能しないのはなぜですか?as3 removeEventListenerが機能しない

クラスのコンストラクタ

public function item(brand:String, title:String, price:Number, mp:Number, 
     path:String, sb1:*, sb2:*):void 

SB1:*とSB2:*オブジェクトのフックです。

これらはリスナーに割り当てられます。この関数が呼び出され

_sb1.addEventListener("Changed", slideBarChanged); // Price 
_sb2.addEventListener("Changed", slideBarChanged); // MegaPixels 

を:

private function slideBarChanged(e:Event):void 
{   
switch(e.target.type) 
{ 
    case "Price": 
     if(int(e.target.currVal) > Math.abs(this.price)) 
     { 
      this._active = false; 
      _sb2.removeEventListener("Changed", slideBarChanged); 
     } 
     else { 
      this._active = true; 
      _sb2.addEventListener("Changed", slideBarChanged); 
     } 
     break; 

    case "MegaPixels": 
     if(int(e.target.currVal) > Math.abs(this.mpixels)) 
     { 
      this._active = false;       
      _sb1.removeEventListener("Changed", slideBarChanged); 
     } 
     else { 
      this._active = true; 
      _sb1.addEventListener("Changed", slideBarChanged); 
     } 
     break;   
} 

Everthingは動作しますが、アイテムが偽= _activeなったときにリスナーが削除されません。 これは実際には次のようになります。

価格が高すぎる場合は、メガピクセルを無視して価格だけを聞いてください。 メガピクセルが高すぎる場合は、価格を無視してメガピクセルだけを聞きます。

私の脳を壊す、どんな助けも大歓迎です。 Thanx。

+0

私は最初にするべきことは機能を分離することだと思います。 megapixelChangeとpriceChange関数があります。また、1つの "this._active"しかありません。どちらがアクティブかどうかをどのように知っていますか?適切な "removeEventListener"に届かないケースステートメントで何かになる可能性があります – Glenn

+0

オブジェクトフックの新しいインスタンスを作成して_sb1と_sb2に割り当てますか? – Allan

答えて

0

多分私はすべてのコードをgrokkedしていないかもしれませんが、私が推測するなら、あなたのオブジェクトの型宣言が原因かもしれないと言います。例えば、あなたがそれらを変更するとどうなりますか

sb1:*, sb2:* 

:とにかく試してみ

sb1:IEventDispatcher, sb2:IEventDisptacher 

簡単。

+0

変更はありません。まだリスナーを削除していない – Steve

0

Adob​​eのdoc show:

EventDispatcherオブジェクトからリスナーを削除します。 EventDispatcherオブジェクトに登録されている一致するリスナーがない場合、このメソッドの呼び出しは無効です。

おそらく見つからない可能性があります。

RemoveListner方法は次のとおりです。

public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 

あなたがメソッドを呼び出すときにuseCaptureを追加したい場合があります。

useCapture:Boolean(default = false) - リスナーがキャプチャフェーズまたはターゲットフェーズとバブリングフェーズのどちらに登録されているかを指定します。リスナーがキャプチャフェーズとターゲットフェーズとバブリングフェーズの両方に登録されている場合は、useCapture()をtrueに設定した呼び出しとuseCapture()をfalseに設定した呼び出しの両方を削除するにはremoveEventListener()を2回呼び出す必要があります。

0

私はCasaLibの大ファンです。拡張された多くの基本ライブラリがあります。そのうちの一つは、RemovableEventDispatcher

ライブラリを試してみて、それが

0

あなたはリスナーが本当に有効であるかどうかを判断するためにwillTrigger()メソッドを使用してみましたができますかどうかを確認することができますか?また、あなたのコードが実際に呼び出されていることを確認するためにトレースを実行しようとしましたか?

+0

私はOPで言ったように、設計どおりに動作しますが、リスナーは削除されません。 – Steve

+0

リスナーが削除されていないことを示すためにFlexUnitでテストケースを作成することをおすすめします。参照:http://pastebin.com/NMqKyN0N –

4

別のノートにも

_sb1.removeEventListener("Changed", slideBarChanged); 

または

_sb2.removeEventListener("Changed", slideBarChanged); 

とは反対に、あなたが代わりに型パラメータの文字列リテラルの定数を解析する必要があり

e.target.removeEventListener("Changed", slideBarChanged); 

をお試しくださいaddEventListener()およびremoveEventListener()メソッドの

const CHANGED:String = "changed"; 

_sb1.addEventListener(CHANGED, slideBarChanged); 
_sb1.removeEventListener(CHANGED, slideBarChanged); 
0

あなたが示したコードでリスナーが割り当てられ、削除された方法には何も問題はないようです。 a)Flashの標準UIエレメントでは、Event.CHANGE定数を使用して変更を伝播します。これは文字列「change」に変換され、リスナーはすべて「Changed」に割り当てられます。一度ネイティブの "変更"にリスナーを追加すると、値が変更されたときにイベントリスナーが正しく呼び出されますが、removeEventListener ("Changed",...)は決して機能しません。いずれにしても、リスナーを割り当てたり削除したりするときには、文字列の代わりに文字列定数を使用して、スペルミスを回避してください。

b)event.targetは、実際のslideBarオブジェクトには解決されませんが、bubblingイベントを使用して一部のネストされたDisplayObjectに解決されます。

c)スライドバーのステージインスタンスは、_sb1および_sb2で参照される同じオブジェクトではありません。これは、ある時点でslideBarの新しいインスタンスを作成しても、アイテムの変数を更新しない場合に発生する可能性があります。これを避けるには、_sb1または_sb2を明示的に指定する代わりにevent.target.removeEventListener()を使用できます。

d)ロジックに問題があります。 removeEventListenerコールが行われたことが確実ですか?たぶんif文が真と評価されることはありませんか?比較のどちらかの側がNaNである場合、またはslideBar値が誤って計算された場合、これが当てはまる可能性があります。

なぜリスナーを削除したいのか分かりません。何らかのフィルタメカニズムを作成しているようですが、this._activefalseに設定しても意味があります後でそれを再度アクティブにするには、引き続きslideBarの変更をリスンする必要があります。

+0

a)mouseUpでchangeイベントを送出する独自のslideBarクラスを使用して、標準UIを使用しません。 – Steve

+0

SliderBarクラスのコードを表示できますか? – Taurayi

1

いいえ、誰かが回答を望んでいる場合は、これが私のやり方です。

簡素化

ロジックは次のようになりますと、私はそれがしたいと、それは正確に作品。

private function slideBarChanged(e:Event):void 
{   
if((int(this._sb1.currVal) > Math.abs(this._price)) || (int(this._sb2.currVal)) > Math.abs(this._mpixels)) 
{ 
    this._active = false; 
} 
    else this._active = true; 
} 

あなたのご協力ありがとうございます。

1

イベントリスナーを複数回追加しています。リスナーを削除しても、すべて削除されないことがあります。次の例では

:あなたがして、余分な条件を追加するか

else { 
    this._active = true; 
    _sb2.addEventListener("Changed", slideBarChanged); 
} 

。hasEventListener、またはあなたが私の優先メソッドを行うことができます。再度追加する前に、行のイベントリスナーを削除してください。愚かですが、すべてのインスタンスでリスナーを追加する前にリスナーを削除しようとすると、重複することはありません。また、存在しないリスナーを削除しようとすると、Flashは自動的に無視します。

複数のリスナーのこの問題は、Flex固有の処理によってFlexで修正されていますが、まだFlashでポップアップします。

関連する問題