2010-08-03 49 views
1

我堅持用一個問題,我不明白爲什麼它的行爲這樣的...Flex 3的 - 問題傳遞參數通過事件

在for循環中,我傳遞的索引作爲事件參數。然而,eventHandler得到錯誤的索引,但是正確的目標...

這是一些代碼。 。作爲類方法:

public function set dataProvider(a:Array):void 
{ 
    var x:int = 0; 
    if(a != null && a.length > 0) 
    { 
     labelsArray = (new ArrayCollection(a)); 
     trace("##############################################################"); 
     for(var i:int = 0; i<a.length; i++) 
     { 
      var btn:NavigationArrowButtonCtrl = new NavigationArrowButtonCtrl(); 
      var s:String = (new ArrayCollection(a)).getItemAt(i).toString(); 
      trace(i + '/' + s); 

      btn.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void{ 
       var lblIndex:int = i; 
       btnAddLblHandler(e, lblIndex); 
      }); 

      this.addChild(btn); 
      this.setChildIndex(btn, 0); 
     } 
     trace("##############################################################"); 
    } 
} 

private function btnAddLblHandler(e:FlexEvent, ind:int):void 
{ 
    trace(labelsArray.length.toString() + '/' + ind.toString()); 
    if(ind < labelsArray.length) 
    { 
     trace('Handler ' + ind + '/' + String(labelsArray.getItemAt(ind))); 
     (e.target as NavigationArrowButtonCtrl).lbl_body.text = String(labelsArray.getItemAt(ind)); 
    } 
} 

這裏的結果跟蹤我越來越:

############################################################## 
0/FINITION 
1/> MOTORISATIONS 
2/> EXTERIEUR 
3/> INTERIEUR 
4/> OPTIONS 
5/> RESUME 
############################################################## 

6/6 
6/6 
6/6 
6/6 
6/6 
6/6 

不知何故,處理越來越的索引只有最後一個值「I」時,它應該在每個循環中獲取'i'的當前值(0/1/2/3/4/5)... 有什麼不對的?

感謝您的幫助! =) 問候,

BS_C3

回答

0

這是我做的到解決問題(範圍事物): - >與以前相同的代碼,只是將'for'部分封裝在一個函數中。

public function set dataProvider(a:Array):void 
{ 
    var x:int = 0; 
    if(a != null && a.length > 0) 
    { 
     labelsArray = (new ArrayCollection(a)); 
     trace("##############################################################"); 
     for(var i:int = 0; i<a.length; i++) 
     { 
      createBtn(i, a); 
     } 
     trace("##############################################################"); 
    } 
} 

private function createBtn(i:int, a:Array):void 
{ 
    var btn:NavigationArrowButtonCtrl = new NavigationArrowButtonCtrl(); 
    var s:String = (new ArrayCollection(a)).getItemAt(i).toString(); 
    trace(i + '/' + s); 

    btn.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void{ 
      var lbl:String = s; 
      btnAddLblHandler(e, lbl); 
     }); 

    this.addChild(btn); 
} 

private function btnAddLblHandler(e:FlexEvent, ind:int):void 
{ 
    trace(labelsArray.length.toString() + '/' + ind.toString()); 
    if(ind < labelsArray.length) 
    { 
     trace('Handler ' + ind + '/' + String(labelsArray.getItemAt(ind))); 
     (e.target as NavigationArrowButtonCtrl).lbl_body.text = String(labelsArray.getItemAt(ind)); 
    } 
} 
1

通過創建按鈕和var lblIndex:int = i;被調用時,for循環已經完成其執行和i值將a.length這爲六在這裏。您可以生成5個不同的功能或使用一些重新設計。

function getListener(i:Number):Function { 
    return function(e:FlexEvent):void{ 
     var lblIndex:int = i; 
     btnAddLblHandler(e, lblIndex); 
    }; 
} 
btn.addEventListener(FlexEvent.CREATION_COMPLETE, getListener(i)); 

它看起來像你試圖設置標籤NavigationArrowButtonCtrl項目一旦創建;更簡單的方法是在該類中聲明[Bindable]變量並將其綁定到lbl_body.text字段。如果你以後不打算更新它,你也不需要真正使用綁定。您只需更新creationComplete處理程序中公共變量的lbl_body.text即可。

因此,代碼如下:

//in NavigationArrowButtonCtrl.mxml 
public var textvar:String; 

//inside the for loop: 
btn.textvar = labelsArray.getItemAt(i).toString(); 
btn.addEventListener(FlexEvent.CREATION_COMPLETE, btnAddLblHandler) 

//inside btnAddLblHandler(e:FlexEvent):void 
btn.lbl_body.text = btn.textvar; 

//you can do it from the NavigationArrowButtonCtrl class itself 
this.lbl_body.text = this.textvar; 

不要依賴e.target - 使用e.currentTarget代替。 target可以是按鈕的某個子節點 - currentTarget將始終具有事件偵聽器註冊的對象。

順便說一句,不要在循環的每次迭代產生相同的陣列集合:

取代:

var s:String = (new ArrayCollection(a)).getItemAt(i).toString(); 

var s:String = labelsArray.getItemAt(i).toString(); 
+0

嗨! 非常感謝您的意見=) 這真的很有幫助,並與你說的玩了一下,我做了一些微小的修改,以解決問題=) – 2010-08-03 14:40:14