最近同事有问到我一个问题:他用ComboBox作为ItemRender修改了DataGrid其中一列的显示。一开始还是没问题的,但随后问题就来了,他新增一条数据,结果之前所有行中ComboBox所选的项都重置了(都选择了ComboBox数据源的第一项)。当时因为忙,我只给出了解决方案,并没有深究其中的原因,今天稍微有点空闲时间,于是把问题具体深究了下。
他的代码是这么写的:
<mx:DataGridColumn headerText="position">
<mx:itemRenderer>
<mx:Component>
<mx:ComboBox dataProvider="{data.position}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
咋一看确实没什么问题,而事实上一新增记录却就重置了combobox的所选项。先理解下flex ItemRender工作特点,ItemRender在确定width、height的DataGrid中,它的数目是一定的,当你更新数据时,只是替换了数据,而ItemRender则是共用的,而且它会把你更新的数据和未更新的数据都重新给ItemRender赋值一遍,到此问题的本质几乎都显露出来了。 <mx:ComboBox dataProvider="{data.position}"/> ,因为新增数据时,原有数据会重新赋值,所以comboBox的dataProvider被重新赋值(尽管该值是同一值),要知道只要comboBox的dataProvider被重新赋值,所选项必然重置。
解决方案:自定义一个component,baseOn ComboBox,在该component种定义一个可绑变量,通过他来改变dataProvider即可,如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" dataProvider="{_myDatas}">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _myDatas:ArrayCollection;
public function set myDatas(value:ArrayCollection):void {
if(_myDatas == value){
return;
}
_myDatas = value;
}
]]>
</mx:Script>
</mx:ComboBox>