首页 > 设计 > WEB开发 > 正文

7.4.创建一个简单的组件作为渲染器和编辑器

2023-08-02 23:09:33
字体:
来源:转载
供稿:网友
7.4.1. 问题
你需要建立一个即可以用于item editor 又可以用于item renderer 的组件,并且item editor 会收到一个数组,我们希望这个数组能以combo box 的形式显示出来。
7.4.2. 解决办法
建立一个己经实现了IDropInListItemRenderer 的组件,并在它里边定义两个states即状态,一个状态用于显示editor 另一个用于显示renderer。当data 发生变化时,即在editor 状态用户做了修改操作,系统将会派发一个ITEM_EDIT_END 事件到这个组件的父组件,父组件收到这个事件后,保存修改的数据到dataProvider 里。
7.4.3. 讨论
把一个item renderer 改装成一个item editor 很容易,在List 这个类里有一个rendererIsEditor 属性,如果这个属性为true,当itemRenderer 被双击时,便进入编辑状态,List 并没有建一个item editor 而是使用itemRenderer 监听并捕获了edit 的事件。

原文中提到DataGridColumn 也有rendererIsEditor 属性,这是对的,但原文中说DataGridColumn 是继承自List,我看了这两个类,它们之间并没有这层关系,它们各自定义了rendererIsEditor 属性。

当用户完成修改后即更新dataProvider,关健在于修改完成后renderer 要派发一个ITEM_EDIT_END 事件。在下边的例子中使用DataGridEvent 传递被修改单元格所在行数和列数,从而确定需要修改dataProvider 中哪些数据。DataGridEvent 对象是在setNewData方法中建立并派发的。setNewData 方法是在ComboBox 的值发生变化时被调用。
+展开
-ActionScript
private function setNewData():void {
_data.selected = selectCB.selectedItem;
dispatchEvent(new DataGridEvent(DataGridEvent.ITEM_EDIT_END,truetrue, _listData.columnIndex,'selected', _listData.rowIndex));
}

在接下来的例子中,这组数据将要用于dataGrid 的显示,下面这组数据相当于在item renderer 里得到的data,它有几个基本属性:name、age、appearance,还有一个数组extras,还有一个selected 属性,用于标记xtras 数组中哪个元素被选中了,这些数据都是可以修改的。
+展开
-ActionScript
{name:"Todd Anderson", age:31, appearance:"Intimidating", extras:["bar""foo","baz"], selected:"bar"}

象这样的数据是很常见的。extras 属性中的数据是专门用做ComboBox 数据源的,selected 是专门用于记录ComboBox 选中项的。但是一般情况下,DataGrid 的renderer 都只是传一个简单的数据。如果DataGridColumn 没有明确指定dataField 属性,整个data对象被传入renderer。正如下边的样子。(原文在这里的描述很容易让人误解,其实不管你有没有指定dataField 属性,都会把整个data 传给renderer。)
+展开
-XML
<mx:DataGrid dataProvider="{DataHolder.genericCollectionTwo}"
width="450itemEditEnd="checkEditedItem(event)id="dg">

<mx:columns>
<mx:DataGridColumn dataField="age"/>
<mx:DataGridColumn dataField="appearance"/>
<mx:DataGridColumn
itemRenderer="oreilly.cookbook.ComboBoxRenderer"
editable="truerendererIsEditor="true"/>

</mx:columns>
</mx:DataGrid>

请注意rendererIsEditor 的位置。
+展开
-XML
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxmlwidth="400"
height="100doubleClickEnabled="truecurrentState="display"
implements="mx.controls.listClasses.IDropInListItemRenderer">

<mx:Script>
<![CDATA[
import mx.events.DataGridEvent;
import mx.events.ListEvent;
import mx.controls.listClasses.BaseListData;
// Internal variable for the property value.
private var _listData:BaseListData;
private var _data:Object = {};
//data 传给renderer 之后,这个组件开始监听鼠标的双击事件,当它收到这个事件时,它将进入editing 状态:
override public function set data(value:Object):void {
_data = value;
if (_data.selected != null ) {
addEventListener(MouseEvent.DOUBLE_CLICK,startEdit);
}
}
override public function get data():Object { return _data; }
private function startEdit(event:Event):void {
if (currentState == "display" ) {
currentState = "edit" ;
addEventListener(FocusEvent.FOCUS_OUT, endEdit);
}
}
private function endEdit(event:Event):void { currentState = "display" ; }
// Make the listData property bindable.
[Bindable("dataChange")]
public function get listData():BaseListData { return _listData; }
// Define the setter method,
public function set listData(value:BaseListData):void { _listData = value; }
private function setNewData():void {
_data.selected = selectCB.selectedItem;
dispatchEvent(new DataGridEvent(DataGridEvent.ITEM_EDIT_END, true,true,_listData.columnIndex,'selected', _listData.rowIndex));
}

]]>
</mx:Script>

在这个例子中,我们使用states,使这个组件从一个只是简单显示数据的item renderer 变成了可以修改数据item editor,这个item editor 含有一个ComboBox:
+展开
-XML
<mx:states>
<mx:State name="edit">
<mx:AddChild>
<mx:ComboBox id="selectCB"
addedToStage="selectCB.dataProvider =
_data.extras;
selectCB.selectedItem = _data.selected
"
change="setNewData()"/>

</mx:AddChild>
</mx:State>
<mx:State name="display">
<mx:AddChild>
<mx:Text id="textaddedToStage="text.text =
_data.selected
"/>

</mx:AddChild>
</mx:State>
</mx:states>
</mx:Canvas>
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表