【发布时间】:2011-10-06 02:26:26
【问题描述】:
我有一个包含项目列表的自定义 Spark ComboBox。我想向 ComboBox 添加一个新项目,说明文本“添加新项目”,在选择时弹出一个窗口来执行一些操作。
我通过在数据提供者中创建一个与实体类型相同的新对象来实现这一点,新对象的 LabelField 具有文本“添加新项目”。我已经覆盖了 set dataProvider 方法并在自定义组合框中。
但这会将值添加到绑定到 DataProvider 的实际列表中。该列表用于业务逻辑。所以我不希望这种情况发生。我有很多实体类。我无法更改所有对象。
我想要的只是在我的自定义组件中实现相同的功能而不更改其他代码。我也尝试创建一个新的 dataProvier 实例,但我注意到当我创建一个新实例时,List 和 dataprovider 的绑定丢失了。
请帮忙。!!
已编辑:
ExtendedComboBox.as
package components
{ 导入 flash.utils.getDefinitionByName;
import mx.collections.ArrayCollection;
import mx.collections.IList;
import spark.components.ComboBox;
import spark.events.DropDownEvent;
public class ExtendedComboBox extends ComboBox
{
private var _addItem:Boolean = false;
private var _addItemLabel:String = "Create New Item" ;
private var _dropDownClass:String = null ;
private var originalDP:IList ;
private var dpEdited:Boolean = false;
public function ExtendedComboBox()
{
super();
this.addItem = true;
this.addEventListener(DropDownEvent.CLOSE, dropDownCloseEventListner );
this.addEventListener(DropDownEvent.OPEN, openDropDownEvent );
}
public function get dropDownClass():String
{
return _dropDownClass;
}
public function set dropDownClass(value:String):void
{
_dropDownClass = value;
}
public function get addItemLabel():String
{
return _addItemLabel;
}
public function set addItemLabel(value:String):void
{
_addItemLabel = value;
}
public function get addItem():Boolean
{
return _addItem;
}
public function set addItem(value:Boolean):void
{
_addItem = value;
}
private function dropDownCloseEventListner(event:DropDownEvent):void{
}
protected function openDropDownEvent(event:DropDownEvent):void{
if(addItem)
{
// if(value) value = new ArrayCollection();
var value:IList ;
if(originalDP == null) value = new ArrayCollection ;
else value = new ArrayCollection( originalDP.toArray() ) ;
var tempObj:Object;
var createItemPresent:Boolean =false ;
if(dropDownClass != null)
{
var TempClass = flash.utils.getDefinitionByName(dropDownClass) as Class;
tempObj = new TempClass();
if(value.length >0)
{
// trace(value.getChildAt(0)[this.labelField]) ;
if(value.getItemAt(0)[this.labelField] == addItemLabel)
createItemPresent = true ;
}
if(!createItemPresent)
{
tempObj[this.labelField] = addItemLabel ;
var sort = (value as ArrayCollection).sort ;
value.addItemAt(tempObj, 0);
(value as ArrayCollection).sort = sort ;
dpEdited = true;
}
}
}
super.dataProvider = value;
}
override public function set dataProvider(value:IList):void{
if(!dpEdited)
{
originalDP = value;
dpEdited = true;
}
/*if(addItem)
{
// if(value) value = new ArrayCollection();
var tempObj:Object;
var createItemPresent:Boolean =false ;
if(dropDownClass != null)
{
var TempClass = flash.utils.getDefinitionByName(dropDownClass) as Class;
tempObj = new TempClass();
if(value.length >0)
{
if(value.getItemIndex(0)[this.labelField] == addItemLabel)
createItemPresent = true ;
}
if(!createItemPresent)
{
tempObj[this.labelField] = addItemLabel ;
var sort = (value as ArrayCollection).sort ;
value.addItemAt(tempObj, 0);
(value as ArrayCollection).sort = sort ;
}
}
}*/
super.dataProvider = value;
}
}
}
MyEntityObj.as
package entity
{ 公共类 MyEntityObj { 私有变量_名称:字符串; 私有变量 _age:int ; 私有变量 _company:String;
public function MyEntityObj()
{
}
public function get company():String
{
return _company;
}
public function set company(value:String):void
{
_company = value;
}
public function get age():int
{
return _age;
}
public function set age(value:int):void
{
_age = value;
}
public function get name():String
{
return _name;
}
public function set name(value:String):void
{
_name = value;
}
}
}
以及实现示例 - ComboImpl.mxml
<?xml version="1.0" encoding="utf-8"?>
import mx.collections.ArrayCollection;
import mx.events.CollectionEvent;
import mx.events.FlexEvent;
[Bindable]
private var samplDP:ArrayCollection;
protected function application1_initializeHandler(event:FlexEvent):void
{
samplDP = new ArrayCollection ;
samplDP.addEventListener(CollectionEvent.COLLECTION_CHANGE, changeHandlerFunc );
var sampVO:MyEntityObj;
for(var i:int = 0; i<5;i++)
{
sampVO = new MyEntityObj;
sampVO.name = "Name " + i;
sampVO.age = i;
sampVO.company = "Company " + i;
samplDP.addItem(sampVO);
}
}
protected function changeHandlerFunc(event:CollectionEvent):void{
var nameList:String = "" ;
for each(var myObj:* in samplDP)
{
nameList += myObj.name + ", " ;
}
changeHandler.text = nameList ;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup>
<s:Label id="changeHandler" />
<components:ExtendedComboBox dataProvider="{samplDP}" labelField="name" addItem="true" dropDownClass="entity.MyEntityObj" addItemLabel="Create Sample" />
</s:VGroup>
正如 set DataProvider Overridden 方法和 DropDownClose 事件中所评论的那样,添加新项目直接影响原始列表。我不希望这种情况发生。
请注意,它只是一个示例实现。我项目中的组件创建实际上是在动作脚本类中动态发生的。
请帮忙。!!
【问题讨论】:
-
你可以通过扩展组件来做到这一点,但我需要看看你到目前为止在做什么。您只需覆盖 getter 和 setter 以省略该值并创建一个自定义方法,该方法将在您需要时返回数据(可能仅在几个地方)。
-
我首先覆盖了 set dataprovider 方法,但是这样做会将元素添加到原始 ArrayCollection,同样当使用来自 .as 的绑定实用程序设置 dataprovider 时,如果存在,则不会调用覆盖的方法里面没有数据。
-
嗨,Nate,请检查代码并发表评论。
标签: apache-flex data-binding combobox custom-component flex-spark