我遇到了一个问题,我无法理解为什么它会像那样......
在for循环中,我将for索引作为事件参数传递。但是,eventHandler得到了错误的索引,但是正确的目标......
这是一些代码。 .as类方法:
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
不知何故,处理程序只获取for索引'i'的最后一个值,因为它应该在每个循环中获得'i'的当前值(0/1/2/3/4/5)。 。 知道什么是错的吗?
感谢您的帮助! =) 的问候,
BS_C3
答案 0 :(得分:1)
创建按钮并调用var lblIndex:int = i;
时,for循环将完成其执行,i
的值将为a.length
,此处为6。您可以生成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();
答案 1 :(得分:0)
这就是我为解决问题所做的工作(范围事项): - &gt;与以前相同的代码,只是将'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));
}
}