定时无刷新更新树型控件(基于定时更新concentrator)

1.树型控件介绍(以下从flex帮助文档中摘得):
Tree控件使用户可以查看排列为可扩展树的层次结构数据。树中的每个项目都可以是叶或分支。叶项目是树中的端点。分支项目可以包含叶或分支项目,也可以为空.

2.
树型控件常用操作及其API
2.1
树型结点数据源赋值

tree.dataProvider = myData;


2.2
展开所有结点

tree.expandChildrenOf(tree.selectedItem,true);

2.3 关闭所有结点

tree.openItems=[];


2.4
添加子节点

var xml:XML=tree.selectedItem as XML;
xml.appendChild("hello");

2.5 删除子节点

tree.dataDescriptor.removeChildAt(tree.selectedItem.parent(),tree.selectedItem,tree.selectedItem.childIndex(),tree.dataProvider);

2.6 获得当前选中的节点引用

var selectedNode:XML=tree.selectedItem as XML;

2.7 解析从服务器传递过来的树型控件数据

//最初的树型数据
var myData:XML;

//
获得树的新XML数据
myData = XML(event.result);

//
缓存集中器的状态和数据
var concentNodeList:XMLList = myData.descendants("concentrator");

//
遍历它的后代列表(具有concentrator标签)
for each (var node:XML in concentNodeList){
arrConcent.addItem({
uid:node.@uid,
statusType:node.@statusType
});
}


3.
项目实现的需求
定时刷新树型控件中的结点,要求:不能出现有闪烁的现象,也就是不能够一次性改变该树型控件的全部数据,不然就会出现刷新闪烁的情况,在这里我们要实现一个伪刷新操作。下面是我的实现思路,如下所示:
1
)一个是之前的请求(保留第一个请求的备份)
2
)另一个请求,实现集中控制器的节点定时查询操作工作
3
)保存之前的树型控件的选中状态
4
)更新树型结点的状态(在这里主要是它的图标变化),要做比较,对比哪些节点发生变化,比较新数据和旧数据的不同。但又要提高它的效率,没有发生变化的节点,则不用做改变操作。

下面是伪代码:

if(B.type.compareTo(A.type){
如果相不相等,则更新它的状态,
同时将该改变保存至原数据中去。
//
保留现场,操作结束
}

4. 代码实现
4.1
初始化定时器操作

//定时器
public var timer:Timer = null;

timer = new Timer(1000 * 15);

//
开始定时任务
startTimer();


/**
*
开始定时任务
* */
public function startTimer():void
{
timer.start();
timer.addEventListener(TimerEvent.TIMER, timerHandler);
trace("
开始定时任务!");

}

/**
*
定时任务
*
* */
private function timerHandler(e:TimerEvent):void{
httpdata2.send();

}


4.2
两个 httpService 的声明操作

<!--使用另一种式,通过请求后台control控制器来实现-->
<s:HTTPService id="httpdata" url="/sems/paneltreeitem.do?action=init"
resultFormat="e4x" result="httpdata_resultHandler(event)"/>

<s:HTTPService id="httpdata2" url="/sems/paneltreeitem.do?action=init"
resultFormat="e4x" result="httpdata_resultHandler2(event)"/>

注意:没有区别,要说区别,只是 id 的不同。

4.3 httpdata
httpData 的响应函数

/**
*
发送HTTPService后,从XML文件中获取数据
*/
protected function httpdata_resultHandler(event:ResultEvent):void
{
//
获得当前选中的节点引用
var selectedNode:XML=myDataTree.selectedItem as XML;

//
获得树的新XML数据
myData = XML(event.result);
//
刷新树
myDataTree.dataProvider = myData;

myDataTree.validateNow();

//
缓存集中器的状态和数据
var concentNodeList:XMLList = myData.descendants("concentrator");

//
遍历它的后代列表
for each (var node:XML in concentNodeList){
arrConcent.addItem({
uid:node.@uid,
statusType:node.@statusType
});
}

//
若存在选中节点则定位
if(selectedNode!=null){
/* var _selectedNodes:XMLList=myData.descendants().((@nodeType == selectedNode.@nodeType) && (@id == selectedNode.@id));

//
展开且定位树节点
if(_selectedNodes!=null&&_selectedNodes.length()>0){
expandParents(_selectedNodes[0]);
} */
}

//
保存分组idname by叶东林2011-11-29
groupArray = new Array();
//
保存uidname by叶东林2011-11-28
nodeContrlArray = new Array();
this.findGroupAndControlNodes(myData.children());

//
默认展开第一个节点
myDataTree.openItems = myData;

myDataTree.expandChildrenOf(myDataTree.selectedItem,true);

myDataTree.validateNow();

}

/**
*
发送HTTPService后,从XML文件中获取数据
*/
protected function httpdata_resultHandler2(event:ResultEvent):void
{

//
每次添加前做清空操作
arrConcent2.removeAll();

//
获得当前选中的节点引用
var selectedNode:XML=myDataTree.selectedItem as XML;

//
获得树的新XML数据
myData2 = XML(event.result);

//
刷新树,在这里不做赋值工作,不然会刷新整个树。
//myDataTree.dataProvider = myData;

// Alert.show("fda");

//
缓存集中器的状态和数据
var concentNodeList2:XMLList = myData2.descendants("concentrator");


//
遍历它的后代列表
for each (var node:XML in concentNodeList2){
arrConcent2.addItem({
uid:node.@uid,
statusType:node.@statusType
});
}

//
若存在选中节点则定位
if(selectedNode!=null){
/* var _selectedNodes:XMLList=myData.descendants().((@nodeType == selectedNode.@nodeType) && (@id == selectedNode.@id));

//
展开且定位树节点
if(_selectedNodes!=null&&_selectedNodes.length()>0){
expandParents(_selectedNodes[0]);
} */
}

//
保存分组idname by叶东林2011-11-29
groupArray = new Array();
//
保存uidname by叶东林2011-11-28
nodeContrlArray = new Array();

this.findGroupAndControlNodes(myData.children());
changeConcentStatus();

}


4.3
核心函数 changeConcentStatus ,它的职责就是实现多结点改变工作。

/**
*
更新其状态
* @param o表示之前的状态数据
* @param 02
表示定时取的状态数据
*
前置条件:保证两个集合都要有数据
*author xuzhongming
* 2012-06-26
*/
public functionchangeConcentStatus():void{
if(arrConcent.length >0 && arrConcent2.length >0){
for(var i:int=0;i<arrConcent.length;i++){
var o:Object = arrConcent.getItemAt(i);
var o2:Object = arrConcent2.getItemAt(i);

if(o["statusType"].toString() != o2["statusType"].toString()){
Alert.show(o["uid"].toString());
updateNodeStatus("concent",o["uid"].toString(),o2["statusType"].toString());
arrConcent.setItemAt({
uid:o["uid"].toString(),
statusType:o2["statusType"].toString()
},i);
}

for(var j:uint = 0 ;j<1000;j++){
//
延时......Do nothing!!!
}
}
}

//
做赋值操作,将之前的值替换成新值
// arrConcent = arrConcent2;

}


4.4updateNodeStatus
函数,它的职责就是单个结点的改变工作

/**
*
更新树节点状态
* @author叶东林
* @since 2011-12-13
* */
public function updateNodeStatus(type:String,uid:String,status:String,power:Number=-1):void{
var items:Array=[];
var list:XMLList=new XMLList();
list[0]=myDataTree.dataProvider[0];

if(type=="term"){
type = SemsConstants.TREE_NODE_NAME_NODECONTRL;
}
else if(type == "concent"){
type = SemsConstants.TREE_NODE_NAME_CONCENTRATOR;
}

//
缓存选中节点
var selectedNode:XML = XML(myDataTree.selectedItem);

//
所有节点状态
// var nodeStatusArray:Array = new Array();
var nodeStatusArray:Vector.<Vector.<Object>>= new Vector.<Vector.<Object>> ();

this.searchItems(type,uid,list,items,nodeStatusArray);

if(items.length == 0){
return;
}


//
展开该节点
var hasOpen:Boolean = false;
if(!myDataTree.isItemOpen(items[0])){
var baseNode:XML = items[0];
while (baseNode.@id.toString() != "0"){
baseNode = baseNode.parent() as XML;
}
myDataTree.expandChildrenOf(baseNode,true);
hasOpen = true;
}



myDataTree.selectedItems=items;
if (myDataTree.selectedItem != null){
if(type == SemsConstants.TREE_NODE_NAME_CONCENTRATOR && status=="ALARM"){
myDataTree.selectedItem.@statusType = "0-0";
}
else{
myDataTree.selectedItem.@statusType = status;
}


if(hasOpen){
for(var j:int = 0; j<nodeStatusArray.length;j++){
var treeNode:XML = nodeStatusArray[j][0] as XML;
var openStatus:Boolean = nodeStatusArray[j][1] as Boolean;
myDataTree.expandChildrenOf(treeNode,openStatus);
}

}

if(selectedNode != null){
myDataTree.selectedItem = selectedNode;
}

//
更新右边图标
displayChatItem(selectedNode);
}


5.
结束语
flex
树型主要是展示数据的层次性,方便用户查看和比较。树型控件比较复杂,用到的数据是基于 XML 格式的数据,我在实现的过程中走了些弯路,我就把我做的东东拿出来讨论。希望对工作和学习有帮助。一起学习,天天进步。

(完,待续 ...............

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值