如何通过事件侦听器传递参数/变量?我使用匿名函数相当有效地克服了这个问题;这是一个非常简单的解决方案,但在一天结束时,它闻起来像一个巨大的功能漏洞,我觉得应该本地提供。
通常情况会继续下去,但是命运会有,现在我实际上需要删除监听器,而当你使用匿名函数时这样做有点时髦。所以,我再次尝试弄清楚如何将参数传递给事件侦听器,以便只需引用该函数即可删除事件侦听器。
看起来很奇怪,我已经克服了这个问题以及,但是,我不喜欢它并厌倦了使用它。在我看来,它是代码味道。但它就像一个魅力。我将变量,对象或其他内容存储在调度MovieClip上。因此,如果我循环访问数据数组,即时生成缩略图,我只需将数据变量(通常是具有多个属性的对象)存储在实际的缩略图MovieClip中。然后我可以通过引用访问事件监听器方法中的所有数据:
event.target.data。 在这个例子中,“data”是持有我想要的信息的变量的名称。因为当我不使用它时出现的另一个问题是,当我循环遍历数组并生成单击以查看大图像的缩略图时,索引不一致。在循环结束时,所有缩略图都将使用最后一个索引“i”打开图像。因此,如果我有一个长度为12的数组,无论你点击什么缩略图,它们都会加载第12个图像。将数据存储到MovieClip本身,创建一个永不改变的可靠引用。
这一直困扰着我一段时间。基本上我想知道的是,这是一个好的做法,那里有更好的解决方案吗?
以下是一些饮食示例。如有必要,我可以发布更详细的例子。所有示例都描绘了一个缩略图,用于在单击时加载大图像。
不使用匿名函数(问题):
tempThumb.addEventListener(MouseEvent.CLICK, loadImage); public function loadImage(_event:MouseEvent):void { // I don't have the variable _url and preparing a hot bath with a cold blade }
使用匿名函数:
tempThumb.addEventListener(MouseEvent.CLICK, function(_event:MouseEvent) { loadImage("large.jpg"); } ); public function loadImage(_url:String):void { // I got the variable _url and packing away the razor blades }
不使用匿名函数,但使用我的臭妖精技术将数据存储到调度事件的MovieClip中
tempThumb.data = "large.jpg"; tempThumb.addEventListener(MouseEvent.CLICK, loadImage); public function loadImage(_event:MouseEvent):void { trace(event.target.data); // I can access the variable }
我对编程术语不了解,所以我将上面的妖精技术称为。在对象中存储/隐藏变量以供以后使用/访问。它解决了我所有的问题并且工作得非常好。但是,如果有更好的方法,我想知道 方式。
答案 0 :(得分:2)
如果MovieClip需要跟踪您点击时需要知道的额外信息,那么我会使用更正式的Leprechaun技术版本。
我创建了一个名为SpecialImage的新类,它扩展了MovieClip并具有存储要加载的url的属性。
根据您创建SpecialImages的方式,您可以在代码中创建它们,也可以将库中的MovieClip链接到此类。
它基本上是一个豪华的妖精,但由于信息与图像MovieClip直接相关,将它们存储在一起感觉就像是最好的。
答案 1 :(得分:2)
(我想你会想看this answer。)
关于你的怀疑,你自己感受到了:你的妖精的臭(双关语)。想象一下,它是一个Sprite而不是MovieClip。它不是动态的,因此除非执行like Richard said,否则无法添加属性。
根据您的示例,这是您希望的更好的解决方案:
tempThumb.addEventListener(MouseEvent.CLICK, loadImage("large.jpg"));
public function loadImage(_url:String):Function {
return function(_event:MouseEvent):void {
// Now you have both variables _url and _event here!
}
}
但是你希望能够删除听众,所以:
var functionLoadImage:Function = loadImage("large.jpg");
tempThumb.addEventListener(MouseEvent.CLICK, functionLoadImage);
public function loadImage(_url:String):Function {
return function(_event:MouseEvent):void {
// Now you have both variables _url and _event here!
}
}
//trace(tempThumb.hasEventListener(MouseEvent.CLICK));
tempThumb.removeEventListener(MouseEvent.CLICK, functionLoadImage);
//trace(tempThumb.hasEventListener(MouseEvent.CLICK));
答案 2 :(得分:1)
如果您不喜欢将数据存储在目标成员中,则可以使用所谓的“委托”。两者都不比另一个好。这主要是偏好。
以下是Delegate类(无内置内容)的示例:http://www.actionscript.org/resources/articles/205/1/The-Delegate-Class/Page1.html
如果eventdispatcher不是你自己的类,这可能是最好的主意。否则,将变量存储在您自己的类中根本不是一个坏主意。只是OOP风格。
干杯。
答案 3 :(得分:1)
是的我知道你的意思。我所做的是扩展事件,然后发送自定义事件。这样我就可以在自定义事件中创建包含必要数据的属性。看起来干净但需要一点努力。这不是理想的,但我不知道一个明显更好的方法。
答案 4 :(得分:1)
可以更好地避免使用匿名函数,因为它们会使代码变得笨拙并且有时会导致内存泄漏。如果我也负责调度事件,我会使用自定义事件,但这不是这种情况。
在这种情况下,我会将URL和影片剪辑存储在两个单独的类级别数组中并使用
var url:String = urlArray[mcArray.indexOf(event.target)];
在事件处理程序中获取URL。
并不是说在动画片段中存储数据有什么问题,但我觉得这不是一个好方法。但是,即使在他们制造困难时遵循最佳实践也不是一个好主意 - 选择权归你所有。
答案 5 :(得分:0)
您可以执行以下操作,这基本上是一种传递自定义数据的更简洁方法。
example code:
public function myCustomEvenListener(e:MouseEvent,myCustomData:Object)
{
//Do whatever you wnat with myCustomData Object here...
}
//this is the function where you add event listeners to components..
public function init():void
{
var myCustomObject:Object=new Object();
myCustomObject.url="http://xyz.com/image.jsp";
myCustomObject.anydata="You can Add anything here";
mycomponent.addEventListener(MouseEvent.CLICK,function (e:MouseEvent) : void {
myCustomEventListener(e,myCustomObject);
});
}
这只是使用匿名函数的另一种方式....
答案 6 :(得分:0)
最好的做法是创建一个为您的thumnbnail扩展MovieClip的自定义类,并让该缩略图调度一个自定义Event类,该类可以存储您的数据:
制作可以将URLEvent
属性与事件一起存储的自定义url
package{
import flash.events.Event;
public class URLEvent extends Event{
public var url:String;
public static const CLICK:String = "URLEventClick"
public function URLEvent(type:String, url:String = "", bubbles:Boolean = false, cancelable:Boolean=false){
super(type, bubbles, cancelable);
this.url = url;
}
override public function clone():Event{
return new URLEvent(type,url,bubbles,cancelable);
}
}
}
创建一个可以存储url
变量的自定义缩略图类,并在单击时发送URLEvent:
package{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Thumbnail extends MovieClip{
protected var url:String;
public function Thumbnail(url:String){
this.url = url;
addEventListener(MouseEvent.CLICK,clickHandler);
}
//the thumbnail captures its own click and dispatches a custom event
protected function clickHandler(event:MouseEvent):void{
dispatchEvent(new URLEvent(URLEvent.CLICK,url));
}
}
现在,您可以使用Thumbnail
类加载每张图片:
tempThumb.addEventListener(URLEvent.CLICK,tempThumbClickHandler);
function tempThumbClickHandler(event:URLEvent):void{
//we can get the url property direct from the URLEvent
loadImage(event.url);
}
这种方法是更好的OOP练习,因为你不需要知道你的event.target是什么类型的对象 - 你从事件类型中确切地知道每个事件将发送什么类型的数据。
答案 7 :(得分:0)
如果我正在寻找这个功能,而且我经常这样做,我会让tempThumb成为一个带有url属性的类。然后:
MyThumbClass(event.target).url //in the MouseEvent.CLICK handler
强类型,易于访问,语法清晰,复杂度低。