2009-08-14 87 views
0

动态处理事件我有暴露字面上几十项活动(您一本关于这是否是好/坏的设计,只知道我没有做那个类切线获得前)的一类。每个事件的事件对象(eventParam在下面的代码)始终有一个toDebugString功能,基本上创建一个包含所有事件对象的属性值的字符串:与函数表达式

propertyName1: propertyValue1 
propertyName2: propertyValue2 
propertyName3: propertyValue3 

它的工作原理,只要创建所有的面板,每个面板的标题都是事件的名称。然而,最大的问题是所有的事件都会在最后面板的TextArea中结束。所以有一些我不明白的匿名方法。就好像循环的每次迭代使用相同的函数,并且在循环的最后一次迭代中,它决定刚刚创建的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); 
    }   
} 

回答

1

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

(有什么事情在Explaining JavaScript scope and closures,查找名为“臭名昭著的循环问题”一节的一点解释更多关于关闭在jibbering。 )

+0

+1谢谢你解释闭门器。我最终创建了一个完整的mxml组件,它代表了包含textArea和事件处理程序的debugSubPanel。在我之前的循环中,我实例化了其中的一个,并将其传递给ResponsesDispatcher的引用和事件的名称。然后在DebugSubPanel类中连接到事件。 – AaronLS 2009-08-16 00:13:36

0

这是我想出的黑客。我真的不喜欢它,但它现在可以工作。仍然对建议开放。

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