as3 removeEventListener не работает - PullRequest
       2

as3 removeEventListener не работает

4 голосов
/ 09 февраля 2011

Это сводит меня с ума. Почему не работают removeEventListeners?

Конструктор класса

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

Все работает, но слушатель не удаляется, когда элемент становится _active = false; Фактически это должно работать так:

Если цена слишком высока, игнорируйте мегапиксели и слушайте только цену. Если мегапиксели слишком высоки, тогда игнорируйте цену и слушайте только мегапиксели.

ломая мой мозг, любая помощь очень ценится. Thanx.

Ответы [ 8 ]

4 голосов
/ 09 февраля 2011

Попробуйте

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

в отличие от

_sb1.removeEventListener("Changed", slideBarChanged); 

или

_sb2.removeEventListener("Changed", slideBarChanged);

Также в отдельной заметке вы должны проанализировать константу вместо строкового литерала для параметра типа методов addEventListener () и removeEventListener ().

const CHANGED:String = "changed";

_sb1.addEventListener(CHANGED, slideBarChanged); 
_sb1.removeEventListener(CHANGED, slideBarChanged); 
1 голос
/ 16 ноября 2011

Вы добавляете прослушиватели событий несколько раз. Удаление слушателя не может удалить все это.

В следующем примере:

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

Вы можете добавить дополнительное условие с помощью .hasEventListener, или вы можете сделать мой предпочтительный метод. Удалите прослушиватель событий на линии, прежде чем добавить его снова. Это глупо, но если вы попытаетесь удалить слушателя, прежде чем добавлять его в каждом случае, вы никогда не будете дублировать. Кроме того, Flash молча игнорирует вас, если вы пытаетесь удалить слушателя, который не существует.

Эта проблема с несколькими прослушивателями исправлена ​​во Flex с некоторой специфической обработкой Flex, но она все еще появляется во Flash.

1 голос
/ 09 февраля 2011

ОК, на всякий случай, если кто-то надеется на ответ, это то, что я сделал.

УПРОЩЕНИЕ

Логика теперь выглядит так, и она работает именно так, как я хочу.

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

Спасибо за вашу помощь - высоко ценится.

0 голосов
/ 09 февраля 2011

Кажется, нет ничего плохого в том, как ваши слушатели назначаются и удаляются в показанном вами коде.Я подозреваю одно из следующего:

a) Стандартные элементы пользовательского интерфейса во Flash используют константу Event.CHANGE для распространения изменений, которая разрешается в строку «change», в то время как ваши слушателивсе назначено на «Изменено».Если только когда вы добавите прослушиватель к собственному «изменению», ваши прослушиватели событий будут правильно вызываться при каждом изменении значения, но removeEventListener ("Changed",...) никогда не будет работать.В любом случае, вы всегда должны использовать строковые константы вместо символьных последовательностей, когда вы назначаете или удаляете слушателей, чтобы избежать ошибок в написании.вложенный DisplayObject с использованием события bubbling .

c) Экземпляры сцены ваших слайдбаров - это не те же объекты, на которые ссылаются _sb1 и _sb2.Это может произойти, если вы в какой-то момент создадите новый экземпляр slideBar, но никогда не будете обновлять переменные элемента.Чтобы избежать этого, вы можете использовать event.target.removeEventListener() вместо явного обращения к _sb1 или _sb2.

d) Что-то не так с вашей логикой.Вы уверены, что removeEventListener звонки когда-либо были сделаны?Возможно, заявления if никогда не оцениваются как истинные?Это может иметь место, если любая из сторон сравнения равна NaN, или если значения slideBar неверно рассчитаны.

Я также не понимаю, почему вы вообще хотите удалить слушателей - кажется, высоздают какой-то механизм фильтрации, и хотя имеет смысл установить this._active на false, если элемент не находится в указанном диапазоне, вам все равно придется прослушивать изменения slideBar, чтобы активировать его позднее.

0 голосов
/ 09 февраля 2011

Вы пытались использовать метод willTrigger (), чтобы определить, действительно ли слушатель активен?Кроме того, вы пытались запустить трассировку, чтобы убедиться, что ваш код действительно вызывается?

0 голосов
/ 09 февраля 2011

Я большой поклонник CasaLib . Есть много базовых библиотек, которые расширены. один из них RemovableEventDispatcher

вы можете попробовать библиотеку и посмотреть, поможет ли это

0 голосов
/ 09 февраля 2011

Adobe док-шоу:

Удаляет прослушиватель из объекта EventDispatcher. Если для объекта EventDispatcher не зарегистрирован соответствующий слушатель, вызов этого метода не имеет никакого эффекта.

Вероятно, он не находит его.

Метод RemoveListner:

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

Возможно, вы захотите добавить useCapture при вызове метода.

useCapture: Boolean (default = false) - Указывает, был ли прослушиватель зарегистрирован для фазы захвата или целевого и пузырькового фаз. Если прослушиватель был зарегистрирован как для фазы захвата, так и для целевого и пузырькового фаз, для удаления обоих требуется два вызова removeEventListener (), один вызов с useCapture (), установленным в true, и другой вызов с useCapture (), установленным в false.

0 голосов
/ 09 февраля 2011

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

sb1:*, sb2:*

Что произойдет, если вы измените их на:

sb1:IEventDispatcher, sb2:IEventDisptacher

Легко попробовать в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...