再议Flex的DataGrid的数据刷新问题

  最近的项目里面使用到了官方的DataGrid,发现他的ItemRenderer刷新问题的确蛮头疼,所以深入的了解了下。以下为个人在项目中碰到的问题的解决思路,相信大家还有其他的解决方法,还望赐教。

  我实现的功能很简单,就是使用一个label来做Itemrenderer,不过要对这个label的样式及数据做些处理。先贴代码:

  

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
	<mx:Script>
		<![CDATA[
			import com.tiantu.unit.filter.CustomFilters;
			private var date:Date = new Date();
			private var statusType:Array = ['武将重伤' , '武将空闲' , '武将编组'];
			private var statusTxt:String;
			
			override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
 			{
				super.updateDisplayList(unscaledWidth , unscaledHeight);
				if(data.SLG_state == 0  &&  int(data.resurge_time)*1000 > date.time)
				{
					statusTxt = statusType[0];
					status.setStyle('color' , 0x777778);
				}
				else if((data.SLG_state == 0 && data.resurge_time*1000 <= date.time || data.SLG_state == 1) && data.RPG_state == 0)
				{
					statusTxt = statusType[1];
					status.setStyle('color' , 0x1713ce);
				}
				else if(data.RPG_state == 3)
				{
					statusTxt = statusType[2];
					status.setStyle('color' , 0x9ac14);
				}
			}
		]]>
	</mx:Script>
	<mx:Label id="status" text="{statusTxt}" textAlign="center" />
</mx:Canvas>

  就是要在不同状态显示不同的数据,很简单。但是当数据量很大的时候再去拖动滚动条你肯定会发现你的数据错乱的厉害,很头疼吧。现在讲讲上面的代码

  其实在上篇文已经讲过官方的DataGrid的数据显示机制了,重要的就是你要让Flex知道你的数据时更新了的,否则他不会帮你重绘,很简单的道理。

  在这个地方我先讲下比较方便的处理方法,只要DataGrid出现滚动条并且你去拉动了,那么你的视图就会执行重绘。这个时候如果你使用了ItemRenderer并且没有数据变化,ok,你的数据必乱。所以我在此直接在更新视图的时候重新设置了label的数据。这样绘制出来的数据就是你当前的数据了。简单吧?呵呵。

  下面再讲下另外一种实现方式:就是重写set data,这个方法就是在数据变化时进行调用,并重新设置值。不过这个方法对没有数据变化并且没有数据交互的时候的兼容如何,我只是使用了checkBox来做渲染器。所以,重写这个方法并且在初始化监听其CHANGE事件并在回调中进行处理。先看代码:

  

	public function DgCheckBoxItem()
		{
			super();
			this.addEventListener(Event.CHANGE , changeHandler);
		}
		
		private var _data:Object;
		private function changeHandler(event:Event):void
		{
			if(_data.hasOwnProperty('selected'))
			{
				_data.selected = this.selected;
			}
		}
		
		override public function get data():Object
		{
			return _data;
		}
		
		override public function set data(value:Object):void
		{
			_data = value;
			if(_data.hasOwnProperty('selected'))
			{
				this.selected = _data.selected; 
			}
		}

这个地方重写set data是很简单的事情,但是请注意重写了setter一定要重写getter,否则外部会无法获取该组件的相关data。

此外如果数据还没更新的话可以向外派发一个FlexEvent.DATA_CHANGE事件以保证组件能监听到数据的更新。好了,知道了原理相信处理相似的问题,你会得心应手,有问题继续交流,欢迎大家留言

posted @ 2010-10-11 20:41  yurong3000  阅读(3481)  评论(0编辑  收藏  举报