Actionscript 3 使用函数表达式动态处理事件
我有一个类,它公开了几十个事件(在你开始讨论这是否是好的/坏的设计之前,只知道我没有创建这个类)。每个事件的事件对象(下面代码中的eventParam)始终具有toDebugString函数,该函数基本上创建了一个包含所有事件对象属性值的字符串:Actionscript 3 使用函数表达式动态处理事件,actionscript-3,actionscript,Actionscript 3,Actionscript,我有一个类,它公开了几十个事件(在你开始讨论这是否是好的/坏的设计之前,只知道我没有创建这个类)。每个事件的事件对象(下面代码中的eventParam)始终具有toDebugString函数,该函数基本上创建了一个包含所有事件对象属性值的字符串: propertyName1: propertyValue1 propertyName2: propertyValue2 propertyName3: propertyValue3 它可以创建所有面板,每个面板的标题都是事件的名称。然而,最大的问题是所
propertyName1: propertyValue1
propertyName2: propertyValue2
propertyName3: propertyValue3
它可以创建所有面板,每个面板的标题都是事件的名称。然而,最大的问题是所有事件最终都会出现在最后一个面板的文本区域。所以我对匿名方法有些不理解。这就好像循环的每个迭代都使用相同的函数,在循环的最后一次迭代中,它决定刚刚创建的debugPanel将是该函数的所有实例都将引用的那个。换句话说,在循环的每个迭代中都会创建一个新的唯一debugSubPanel和TextArea,但只有一个debugResponseListener事件处理程序由循环的所有迭代共享。所以我的问题是,如何动态创建事件处理程序函数,使其与我希望的debugSubPanel保持关联
public function debugPanelCreated(event:FlexEvent)
{
//iterate through all of the events exposed by mClient.ResponsesDispatcher
//where key is the name of the event
for (var key:String in mClient.ResponsesDispatcher.respMap)
{
//for each event, create a panel containing a text box
var debugSubPanel:Panel = new Panel();
debugSubPanel.title = debugSubPanel.label = key;
var debugSubPanelTextArea:TextArea = new TextArea();
debugSubPanel.addChild(debugSubPanelTextArea);
var debugResponseListener:Function =
function (eventParam :Object) : void
{
//use debugString function to write the properties
//of eventParam to the text box
debugSubPanelTextArea.text = eventParam .toDebugString();
};
//listen to this event:
mClient.ResponsesDispatcher.addEventListener(key,debugResponseListener);
//add the panel for this event
debugPanel.addChild(debugSubPanel);
}
}
这就是我想出的方法。我真的不喜欢,但现在可以用了。仍然接受建议
public class ResponseDispatcherToDebugStringHelper
{
public var textArea:TextArea;
public function responseToDebugStringHandler(eventParam:Object) : void
{
//use debugString function to write the properties
//of eventParam to the text box
textArea.text = eventParam.toDebugString();
}
}
public function debugPanelCreated(event:FlexEvent)
{
//iterate through all of the events exposed by mClient.ResponsesDispatcher
//where key is the name of the event
for (var key:String in mClient.ResponsesDispatcher.respMap)
{
//for each event, create a panel containing a text box
var debugSubPanel:Panel = new Panel();
debugSubPanel.title = debugSubPanel.label = key;
var debugSubPanelTextArea:TextArea = new TextArea();
debugSubPanel.addChild(debugSubPanelTextArea);
var helper:ResponseDispatcherToDebugStringHelper =
new ResponseDispatcherToDebugStringHelper();
helper.textArea = debugSubPanelTextArea;
//listen to this event:
mClient.ResponsesDispatcher.addEventListener(key,helper.responseToDebugStringHandler);
//add the panel for this event
debugPanel.addChild(debugSubPanel);
}
}
Actionscript包含一个称为闭包的功能,这意味着当您创建并调用内部函数时,其父函数的变量仍然可用。(这就是
debugResponseListener=function()…
的工作方式。)问题是,只有在调用该函数时才会创建闭包,并且它使用上一次设置中的变量值
您可以通过创建一个返回所需侦听器函数的函数来解决这个问题
function makePanelListener(debugSubPanelTextArea:TextArea) : Function
{
return function(eventParam :Object) : void {
//use debugString function to write the properties
//of eventParam to the text box
debugSubPanelTextArea.text = eventParam .toDebugString();
}
}
在原始代码中:
var debugResponseListener:Function = makePanelListener(debugSubPanelTextArea);
(这里有一些关于中发生了什么的解释,请查找“臭名昭著的循环问题”部分。有关闭包的更多信息,请访问。)+1感谢您对闭包的解释。我最终只是创建了一个完整的mxml组件来表示debugSubPanel,其中包含textArea和事件处理程序。在上一个循环中,我实例化了其中一个,并向其传递了对ResponseDispatcher的引用和事件名称。然后在DebugSubPanel类中,我连接到事件。