2009-08-14 88 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); 
    }   
}