`
keren
  • 浏览: 1585112 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Flex 对ArrayCollection的重构

    博客分类:
  • Flex
阅读更多
由于项目的需要,对ArrayCollection进行重构,包括如下功能:
1,排序
2,moveFirst moveLast moveNext movePre 进行记录导航 和选择某个index的对象
3,删除,更新,插入,添加记录的功能
4,过滤
以下是例子:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();">
<mx:Script>
	<![CDATA[
		import mx.collections.CursorBookmark;
		import com.hexagonstar.util.debug.Debug;
		import org.app.utils.common.collections.MyArrayCollection;
		import com.adobe.serialization.json.JSON;
		var arr:Array=[
			{a:1,b:1,c:1},
			{a:21,b:21,c:21},
			{a:12,b:12,c:12},
			{a:10,b:10,c:10},
			{a:2,b:2,c:2}
			];
		[Bindable]
		var coll:MyArrayCollection = null;
		[Bindable]
		var scc:String = null;
		private function init():void{
			coll =new MyArrayCollection(arr);
			//var sortArr:Array=[{name:"a"},{name:"b"}];
			//coll.sortCollection(sortArr);
			src.text= coll.toString();
			//dest.text = JSON.encode(coll.currentItem);
			scc = coll.toString();
			dest.text = scc;
			//keywords
			coll.keywords=["a"];
		}
		
		private function insert():void{
			var s:String = src.text;
			var o:Object = JSON.decode(s);
			coll.insertItem(o);
			scc = coll.toString();
			dest.text = scc;
		}
		private function append():void{
			var s:String = src.text;
			var o:Object = JSON.decode(s);
			coll.appendItem(o);
			scc = coll.toString();
			dest.text = scc;
		}
		private function moveFirst():void{
			var o:Object = coll.moveFirst();
			dest.text = JSON.encode(o);
		}
		private function moveLast():void{
			var o:Object = coll.moveLast();
			dest.text = JSON.encode(o);
		}
		private function moveNext():void{
			var o:Object = coll.moveNext();
			dest.text = JSON.encode(o);
		}
		private function movePre():void{
			var o:Object = coll.movePrevious();
			dest.text = JSON.encode(o);
		}
		private function doClear():void{
			dest.text = "";
		}
		private function doUpd():void{
			var o:Object = JSON.decode(src.text);
			coll.updateItem(o);
			o = coll.currentItem;
			dest.text = JSON.encode(o);
		}
		private function doDel():void{
			var o:Object = JSON.decode(src.text);
			var flg:Boolean = coll.remove();
			Debug.trace("--remove:"+flg);
			scc = coll.toString();
			dest.text = scc;
		}
	]]>
</mx:Script>
	<mx:TextArea id="src" x="25" y="40" width="267" height="103"/>
	<mx:Button x="25" y="10" label="更新" click="doUpd();"/>
	<mx:Button x="188" y="10" label="删除" click="doDel();"/>
	<mx:Button x="244" y="10" label="排序"/>
	<mx:Button x="76" y="10" label="插入" click="insert();"/>
	<mx:Button x="132" y="10" label="添加" click="append();"/>
	<mx:TextArea id="dest" x="300" y="40" width="333" height="103" editable="false" text="{scc}"/>
	<mx:Button x="25" y="299" label="|&lt;" toolTip="第一个" click="moveFirst();"/>
	<mx:Button x="125" y="299" label="&gt;&gt;" toolTip="后一个" click="moveNext();"/>
	<mx:Button x="73" y="299" label="&lt;&lt;" toolTip="前一个" click="movePre();"/>
	<mx:Button x="177" y="299" label="&gt;|" toolTip="最后一个" click="moveLast();"/>
	<mx:DataGrid x="25" y="151" width="608" height="143" dataProvider="{coll}">
		<mx:columns>
			<mx:DataGridColumn headerText="ColumnA" dataField="a"/>
			<mx:DataGridColumn headerText="ColumnB" dataField="b"/>
			<mx:DataGridColumn headerText="ColumnC" dataField="c"/>
		</mx:columns>
	</mx:DataGrid>
	<mx:Button x="585" y="10" label="清空" toggle="true" click="doClear();"/>
</mx:Application>

以下是源码:
/**
 * 用法:
 * coll=new ArrayCollection(
 * 			[
 * 			 {name: "Martin Foo", age: 25}, 
 * 			 {name: "Joe Bar", age: 15}, 
 *           {name: "John Baz", age: 23}
 *          ]
 * );
 * coll.addItemAt({name: "James Fez", age: 40}, 0);
 */
package org.app.utils.common.collections
{	
	import flash.events.Event;
	
	import mx.collections.ArrayCollection;
	import mx.collections.CursorBookmark;
	import mx.collections.IViewCursor;
	import mx.collections.Sort;
	import mx.collections.SortField;
	import mx.events.FlexEvent;
	import mx.logging.ILogger;
	
	import org.app.framework.AppContext;
	import org.app.utils.common.MyJSONUtils;
	import org.app.utils.log.MyLoggerManager;

	public class MyArrayCollection extends ArrayCollection
	{
		////////////////////////////////////////////////////////////////////////
		/*排序规则参数*/
		public static const RL_NAME:String = "name";//要排序的字段的名称。[String]
		public static const RL_CASEINSENSITIVE:String = "caseInsensitive";//Boolean 指定此字段的排序是否应不区分大小写。
		public static const RL_DESCENDING:String = "descending";//Boolean 指定此字段是否应按降序排序。
		/*事件相关*/
		//光标位置更新时的事件
		public static const EVENT_CURSOR_UPDATE:String = "event_cursor_update";
		/*Object 指定当要进行排序的字段包含数值 (number/int/uint) 
		 * 或数值的字符串表示形式时,比较运算符是否使用数值比较。*/
		public static const RL_NUMERIC:String = "numeric";
		////////////////////////////////////////////////////////////////////////
		private var logger:ILogger = MyLoggerManager.getLogger("MyArrayCollection",AppContext.getInstance().appLogTarget);
		////////////////////////////////////////////////////////////////////////
		/*游标*/
		private var _cursor:IViewCursor = null;//当前游标
		private var _currentItem:Object = null;//当前游标指向对象
		/*如果是JSON对象,那么有keys*/
		private var _keys:Array = null;//该数组包含的json properties
		private var _keywords:Array = null;//哪些properties是主键,用于判断重复
		public function MyArrayCollection(source:Array=null)
		{
			super(source);
			//取得当前的光标对象
			this._cursor = this.createCursor();
			//注册光标位置更新事件
			this._cursor.addEventListener(FlexEvent.CURSOR_UPDATE,fireCursorUpdate,false,0,true);
			//給当前光标对象赋值--就会触发cursor update事件
			this._cursor.seek(CursorBookmark.CURRENT);
			//初始化keys 或者 获取keys
			this.fetchKeys();
		}
		
		////////////////////////////////////////////////////////////////////////
		/**
		 * 当光标位置更新时触发的事件,在这取得当前光标位置的值,
		 * 其他地方光标移动时不要給 currentItem赋值了。
		 * @param FlexEvent
		 * @return
		 */
		private function fireCursorUpdate(event:FlexEvent):void{
			//取得当前的值
			this._currentItem = (event.currentTarget as IViewCursor).current;
			//防止 moveLast moveFirst抛出多2个事件,只有当前有对象值了,才抛出
			var a:String = "不抛出";
			if (this._currentItem) {
				a="抛出";
				this.dispatchEvent(new Event(EVENT_CURSOR_UPDATE));
			}
			var s:String = MyJSONUtils.encode(this._currentItem);
			logger.debug("--触发了 cursor update 事件,当前对象:"+s+"["+a+"]");
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		public function set cursor(cursor:IViewCursor):void{
			this._cursor = cursor;
		}
		public function get cursor():IViewCursor{
			return this._cursor;
		}
		public function set currentItem(o:Object):void{
			//替换掉当前对象里面的值
			this.updateItem(o);
			//this._currentItem = o;
		}
		public function get currentItem():Object{
			return this._currentItem;
		}
		////////////////////////////////////////////////////////////////////////
		public function fetchKeys():void{
			if(this.length>0){
				var o:Object = this.getItemAt(0);
				this._keys = MyJSONUtils.fetchKeys(o);
			}else{
				this._keys = [];
			}
		}
		public function getKeys():Array{
			if(this._keys.length<=0){
				this.fetchKeys();
			}
			return this._keys;
		}
		public function set keywords(k:Array):void{
			this._keywords = k;
		}
		public function get keywords():Array{
			return this._keywords;
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		
		/**
		 * 检查是否存在某个条件的对象??????
		 * @param Object  json object eg:{name:"xxx_name", age:34 .....}
		 * @param String 比较类型 采用Sort里面引用的常量
		 * @return int 存在的个数
		 * 
		 * @see mx.collections.Sort
		 */
		public function checkExist(conditionObj:Object,mode:String=Sort.ANY_INDEX_MODE):int{
			var sort:Sort = new Sort();
			return sort.findItem(this.source,conditionObj,mode);   
		}
		
		/**
		 * [这个比较 很慢]
		 * 检查是否存在某个对象,其中keys指根据哪些key进行比较,如果为空,那么根据全部key来比
		 * @param Object
		 * @param Array 要比较的key
		 * @return Boolean true存在
		 */
		public function isExist(o:Object,keys:Array=null):Boolean{
			var key1:Array = keys;
			if(key1==null){
				key1 = MyJSONUtils.fetchKeys(o);
			}
			var item1:String = null;
			var l:int=key1.length;
			for each(var obj:Object in this){
				var flg:int = 0;
				for(var i:int=0;i<l;i++){
					item1=key1[i];
					if(o[item1]==obj[item1]){
						flg++;
					}
				}
				if(flg==l)return true;
			}
			return false;
		}
		/**
		 * 覆盖该方法,来做重复检查
		 * @param Object 要比较的对象
		 * @return Boolean true存在
		 */
		override public function contains(item:Object):Boolean{
			return isExist(item,this._keywords);
		}
		////////////////////////////////////////////////////////////////////////
		/**
		 * 按照一定的规则排序,可以多个字段同时排序:
		 * -- name : String 要排序的字段的名称。 
		 * -- caseInsensitive : Boolean 指定此字段的排序是否应不区分大小写。 
		 * -- descending : Boolean 指定此字段是否应按降序排序。
		 * -- numeric : Object 指定当要进行排序的字段包含数值 (number/int/uint) 
		 *              或数值的字符串表示形式时,比较运算符是否使用数值比较。 
		 * eg:[{name:'age',caseInsensitive:true,descending:false,numeric:null},
		 *                   {name:'age',descending:false}...]
		 *   是个数组,而且 里面是json对象,包含四个元素:name,caseInsensitive,descending,numeric,
		 *   其中,name是必须的,其他的可选。
		 * @param Object 类似上面的写
		 * @return
		 * @see mx.colloections.SortField
		 * 
		 */
		public function sortCollection(conditionObj:Array):void{
			var leng:int = conditionObj.length;
			var fields:Array = [];
			var sortField:SortField = null;
			var o:Object=null;
			
			var name:String=null;
			var caseInsensitive:Boolean=false;
			var descending:Boolean = false;
			var numeric:Object = null;
			for(var i:int=0;i<leng;i++){
				o = conditionObj[i];
				sortField = new SortField();
				//加入参数
				sortField.name=o[MyArrayCollection.RL_NAME];
				
				var tmp:Object = o[MyArrayCollection.RL_CASEINSENSITIVE];
				caseInsensitive=tmp==null?false:true;
				sortField.caseInsensitive=caseInsensitive;
				
				tmp = o[MyArrayCollection.RL_DESCENDING];
				descending=tmp==null?false:true;
				sortField.descending=descending;
				
				tmp = o[MyArrayCollection.RL_NUMERIC];
				numeric=tmp==null?null:tmp;
				sortField.numeric=numeric;
				//加入比较器
				fields.push(sortField);
			}
			var sort:Sort = new Sort();
			sort.fields=fields;
			this.sort = sort;
			this.refresh();
		}
		////////////////////////////////////////////////////////////////////////
		/**
		 * 过滤,首先必须知道自己要过滤的集合里面有些什么字段,
		 * coll = new ArrayCollection([
		 *                      {name:"Martin Foo", age:25},      
         *                      {name:"Joe Bar", age:15},      
         *                      {name:"John Baz", age:23},      
         *                      {name:"Matt Baz", age:21}]);
         * 那么func:
         * private function filterFunc(value:Object):Object {      
         *  if(Number(value.age) > 21) {      
        *    return true;      
         *  }
         *  return false;      
         *} 
         * @param Function 如上
         * @return
		 */
		public function filterCollection(filterFunc:Function):void{
			this.filterFunction = filterFunc;
			this.refresh();
		}
		////////////////////////////////////////////////////////////////////////
		
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		/**
		 * 取得第一个对象,根据cursorMove 来判断是否移动光标
		 * @param Boolean 是否移动当前光标
		 * @return Object 第一个位置的对象
		 */
		public function firstItem(cursorMove:Boolean=true):Object{
			if(cursorMove){
				return this.moveFirst();
			}
			return this.getItemAt(0);
		}
		/**
		 * 取得最后一个对象,根据cursorMove 来判断是否移动光标
		 * @param Boolean 是否移动当前光标
		 * @return Object 最后一个位置的对象
		 */
		public function lastItem(cursorMove:Boolean=true):Object{
			if(cursorMove){
				return this.moveLast();
			}
			return this.getItemAt(this.length-1);
		}
		/**
		 * 在最后位置插入对象,会检查是否存在相同的对象.
		 * @param Object
		 * @return Boolean true成功 false失败
		 */
		public function appendItem(o:Object):Boolean{
			//该方法检查每个元素都相同
			var exist:Boolean= this.contains(o);
			if(!exist){
				this.addItem(o);
				//当前游标处理
				this.moveCursorTo(o);
				if(this._currentItem){
					return true;
				}
			}
			return false;
		}
		
		/**
		 * 在当前位置插入一个对象
		 * @param Object 
		 * @return Boolean
		 */
		public function insertItem(o:Object):Boolean{
			//该方法检查每个元素都相同
			var exist:Boolean= this.contains(o);
			if(!exist){
				this._cursor.insert(o);
				//当前游标处理
				this.moveCursorTo(o);
				if(this._currentItem){
					return true;
				}
			}
			return false;
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		/**
		 * 删除当前光标指向的对象,并选择下一个对象,如果下一个对象为空,那么选择最后一个
		 * @return Object 当前被删除的对象
		 * 
		 */
		public function remove():Object {
			var o:Object=this._cursor.remove();
			if (!this._currentItem) {
				this._cursor.movePrevious();
			}
			return o;
		}
		/**
		 * 删除指定的对象
		 * @param Object
		 * @return Boolean true成功 
		 */
		public function removeItem(o:Object):Boolean{
			this.moveCursorTo(o);
			var o:Object = this.remove();
			if(o)return true;
			return false;
		}
		
		/**
		 * 删除所有数据
		 */
		override public function removeAll():void{
			super.removeAll();
			this.source = [];
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		/**
		 * 更新当前光标指向的对象
		 * @param Object 新的对象
		 * @return
		 */
		public function updateItem(o:Object):void{
			var keys:Array = MyJSONUtils.fetchKeys(o);
			var l:int = keys.length;
			var key:String=null;
			for(var i:int=0;i<l;i++){
				key = keys[i];
				if(this._currentItem[key]){
					this._currentItem[key]=o[key];
					this.itemUpdated(this._currentItem);//这个会令ui更新
				}
			}
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		/**
		 * 把光标移到指定的对象上,
		 * @param Object 目标对象
		 * @return Object 当前选择的对象
		 */
		public function moveCursorTo(o:Object):Object {
			//当前游标处理
			var index:int=this.getItemIndex(o);
			return this.moveCursorByIndex(index);
		}
		public function moveCursorByIndex(index:int):Object{
			if(index < 0 || index >= this.length)return null;
			var oldIndex:int = this.getItemIndex(this._currentItem);
			var offset:int = 0;
			if (oldIndex > index) {
				offset = -(oldIndex - index);
			} else if (oldIndex < index) {
				offset = index - oldIndex;
			}
			this._cursor.seek(this._cursor.bookmark, offset);
			return this._currentItem;
		}
		
		/**
		 * 光标指向第一个位置,返回第一个位置的值 
		 * @return Object 当前光标位置的对象
		 */
		public function moveFirst():Object{
			//当前游标处理
			this._cursor.seek(CursorBookmark.FIRST);
			//当前对象设置值
			//在cursor update 事件里面处理了
			//返回当前对象
			return this._currentItem;
		}
		
		/**
		 * 光标指向最后一个位置,返回最后一个位置的值 
		 * @return Object 当前光标位置的对象
		 */
		public function moveLast():Object{
			//当前游标处理
			this._cursor.seek(CursorBookmark.LAST);
			//当前对象设置值
			//在cursor update 事件里面处理了
			//返回当前对象
			return this._currentItem;
		}
		
		/**
		 * 光标指向下一个位置,返回光标指向位置的对象
		 * @return Object 当前光标位置的对象
		 */
		public function moveNext():Object {
			if (!this._cursor.afterLast) {
				this._cursor.moveNext();
				//this._currentItem = this._cursor.current;
				if (!this._currentItem) {
					this._cursor.movePrevious();
				}
			}
			return this._currentItem;
		}
		
		/**
		 * 光标指向上一个位置,返回光标指向位置的对象
		 * @return Object 当前光标位置的对象
		 */
		public function movePrevious():Object {
			if (!this._cursor.beforeFirst) {
				this._cursor.movePrevious();
				if (!this._currentItem) {
					this._cursor.moveNext();
				}
			}
			return this._currentItem;
		}
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		/**
		 * 把值转成字符串
		 * @return String 
		 */
		override public function toString():String{
			var s:String = "";
			var l:int=this.length;
			for(var i:int=0;i<l;i++){
				s+=MyJSONUtils.encode(this.getItemAt(i));
			}
			return s;
		}
		
		
	}//end class
}//end package
0
0
分享到:
评论

相关推荐

    Flex:ArrayCollection转xml形式的实例

    ArrayCollection是基于Array的,但提供了对数据的更高级别的访问,如排序和过滤功能。在某些情况下,我们需要将ArrayCollection转换为XML格式,以便于数据交换或存储。本实例将详细介绍如何实现这一转换。 首先,...

    Flex的Array和ArrayCollection

    Flex的Array和ArrayCollection

    Flex Tree 通过Arraycollection转化为XML数据源,新增、删除、修改功能的整合

    本篇文章将聚焦于如何将ArrayCollection转换为XML数据源,并实现Flex Tree组件的新增、删除和修改功能。以下是详细的解释和步骤。 首先,ArrayCollection是Flex中常用的数据结构,它是一个动态数组,支持数据绑定和...

    ArrayCollection求最大值,最小值,排序

    在IT行业中,ArrayCollection是ActionScript 3.0和Flex框架中的一个重要数据结构,它扩展了Array类,提供了对数据的双向绑定和事件通知功能。ArrayCollection不仅支持数组的操作,还具备列表的数据管理特性,因此在...

    用ArrayCollection当做flex中Tree控件的DataProvider

    本文将详细探讨如何使用`ArrayCollection`作为Flex中的`Tree`控件的数据提供者,以替代通常使用的XML数据源。 首先,让我们理解`ArrayCollection`的概念。`ArrayCollection`是Flex中的一个类,它继承自`...

    ArrayCollection不完全绑定

    在Flex编程中,ArrayCollection是一种常用的集合类,它继承自Array类并添加了对数据绑定的支持。然而,尽管ArrayCollection通常被用作数据绑定的主要工具,但在特定情况下,可能会遇到“ArrayCollection不完全绑定”...

    FLEX ArrayCollection删除过滤的数据问题解决

    在Flex开发中,ArrayCollection是一种常用的集合类,它继承自Array并添加了对数据绑定和事件处理的支持。然而,当ArrayCollection应用了过滤器后,直接使用`removeItemAt()`方法尝试删除过滤后的数据可能会遇到问题...

    flex操作数据库, flex操作本地sql数据库

    var employees:ArrayCollection = event.result as ArrayCollection; // 处理查询结果 } function onQueryError(event:FaultEvent):void { trace("查询出错:" + event.fault.message); } ``` 六、优化与安全 ...

    flex带复选框的tree,flex checkboxtree

    在Flex中,Tree组件是用于显示层次结构数据的控件,而"flex带复选框的tree"(Flex CheckboxTree)则是对Tree组件的一种扩展,增加了复选框功能,用户可以对树形结构的节点进行选择或全选操作,常用于权限管理、配置...

    flex实时更新曲线图

    这意味着图表组件的数据提供者可以是任何实现了ICollectionView接口的对象,如ArrayCollection或XMLList。当这个数据源发生改变时,图表会自动反映出这些变化。 7. **事件处理**:在实时更新中,事件处理是必不可少...

    Flex第一步

    - **兼容性提升**:Flex持续优化对新设备和浏览器的支持。 - **性能优化**:通过改进编译器和运行时环境,提高应用性能。 - **跨平台拓展**:虽然Flex已经支持多种平台,但仍在探索更多可能性。 - **社区支持**:...

    12条常用Flex代码 值得收藏

    对Flex开发者来说,掌握基本的Flex代码是非常必要的。以下是12条常用的Flex代码,涵盖了Flex的多个方面,旨在提高开发者的开发效率和编程水平。 1. 复制内容到系统剪贴板 在Flex应用程序中,经常需要将内容复制到...

    Flex如何让前台链接后并访问数据库

    var employees:ArrayCollection = event.result as ArrayCollection; employeeList.dataProvider = employees; } ``` 在这个例子中,`employeeService`调用了后台的"getEmployees"方法,当服务返回结果时,`...

    Flex连接数据库三种方法

    - 调用RemoteObject的方法,当服务端返回数据后,可以通过事件监听器处理数据,将ArrayList转换为Flex能识别的数据结构,如ArrayCollection。 4. **展示数据**: - 将从服务端获取的公告数据绑定到Flex界面组件,...

    flex组件LIST使用

    在Flex中,`ArrayCollection`是用于管理列表数据的一种常见方式。它不仅提供了基本的数据存储功能,还支持事件通知、排序和过滤等功能,非常适合用作`List`组件的数据源。示例中的`myDP`变量即为一个`...

    flex实现数据表格。

    1. **数据绑定**:Datagrid可以直接与数据提供者进行绑定,数据提供者可以是Array、ArrayCollection或其他支持ICollectionView接口的数据源。这意味着你可以动态地更新数据源,Datagrid会自动反映这些更改。 2. **...

    flex 拓扑图dome

    在Flex中,可以使用`ArrayCollection`或`XMLList`等数据结构来存储和操作这些数据。 7. **自定义组件**:如果预定义的组件无法满足需求,可以创建自定义组件。例如,你可以创建一个`TopologyNode`组件来表示网络...

    Flex添加右键菜单

    在Flex开发中,有时我们需要为用户界面添加自定义的右键菜单,以便提供更多的交互功能。本教程将指导你如何在Flex项目中实现这一功能,主要涉及以下知识点: 1. **右键菜单库的引入**: 首先,你需要下载一个名为`...

    flex8 网格控件

    1. **数据绑定**:Flex8的DataGrid控件可以轻松地绑定到各种数据源,包括ArrayCollection、XMLListCollection或直接连接到服务器的数据服务。这使得数据的更新和显示变得简单。 2. **列定制**:开发者可以自定义...

Global site tag (gtag.js) - Google Analytics