这让我发疯了。为什么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 = false时,不会删除侦听器; 实际上这应该是这样的:
如果价格太高,则忽略百万像素,只听取价格。 如果百万像素太高,则忽略价格,只收听百万像素。
打破我的大脑,非常感谢任何帮助。 感谢名单。答案 0 :(得分:4)
尝试
e.target.removeEventListener("Changed", slideBarChanged);
而不是
_sb1.removeEventListener("Changed", slideBarChanged);
或
_sb2.removeEventListener("Changed", slideBarChanged);
另外,在单独的注释中,您应该为addEventListener()和removeEventListener()方法的type参数解析常量而不是字符串文字。
const CHANGED:String = "changed";
_sb1.addEventListener(CHANGED, slideBarChanged);
_sb1.removeEventListener(CHANGED, slideBarChanged);
答案 1 :(得分: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;
}
Thanx为您提供所有帮助 - 非常感谢。
答案 2 :(得分:1)
您要多次添加事件侦听器。删除侦听器可能无法全部删除。
在以下示例中:
else {
this._active = true;
_sb2.addEventListener("Changed", slideBarChanged);
}
您可以使用.hasEventListener添加额外的条件,也可以使用我的首选方法。在再次添加之前删除该行上的事件侦听器。这很愚蠢,但是如果你在每个实例中添加它之前尝试删除它,那么你永远不会重复。此外,如果您尝试删除不存在的侦听器,Flash会默默地忽略您。
多个侦听器的这个问题在Flex中已经修复,并且具有一些特定于Flex的处理,但它仍然会在Flash中弹出。
答案 3 :(得分:0)
也许我没有弄清楚所有代码,但如果我猜测,我会说可能是对象的类型声明是原因。例如,
sb1:*, sb2:*
如果将其更改为:
会发生什么sb1:IEventDispatcher, sb2:IEventDisptacher
无论如何都很容易尝试。
答案 4 :(得分:0)
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。
答案 5 :(得分:0)
我是CasaLib的粉丝。有很多基础库可以扩展。其中一个是RemovableEventDispatcher
你可以试试这个库,看看是否有帮助
答案 6 :(得分:0)
您是否尝试过使用willTrigger()方法来确定侦听器是否真的有效?此外,您是否尝试在其中运行跟踪以确保实际调用您的代码?
答案 7 :(得分:0)
在您显示的代码中分配和删除侦听器的方式似乎没有任何问题。我怀疑其中一个:
a)Flash中的标准UI元素使用Event.CHANGE
常量来传播更改,这些更改将解析为字符串“change”,而您的侦听器都已分配给“已更改”。如果您只是在本机“更改”中添加了一个侦听器,那么只要值发生更改,就会正确调用您的事件侦听器,但removeEventListener ("Changed",...)
将无法正常工作。在任何情况下,在分配或删除侦听器时,应始终使用字符串常量而不是字符序列,以避免拼写错误。
b)您的event.target
未解析为实际的slideBar对象,而是使用bubbling事件解析为某个嵌套DisplayObject
。
c)slideBars的舞台实例与_sb1和_sb2中引用的对象不同。如果您在某个时刻创建了一个新的slideBar实例,但从不更新该项的变量,则可能会发生这种情况。为避免这种情况,您可以使用event.target.removeEventListener()
而不是明确地处理_sb1或_sb2。
d)你的逻辑出了问题。你确定有removeEventListener
次电话吗?或许if语句永远不会评估为真?如果比较的任何一方是NaN
,或者如果计算的slideBar值错误,则可能是这种情况。
我也不明白你为什么要删除监听器 - 似乎你正在创建某种过滤机制,而如果将this._active
设置为false
则有意义item不在指定的范围内,您仍然需要侦听slideBar更改以便稍后重新激活它。