Tree控件使用户可以查看排列为可扩展树的层次结构数据。树中的每个项目都可以是叶或分支。叶项目是树中的端点。分支项目可以包含叶或分支项目,也可以为空.
2.树型控件常用操作及其API
2.1树型结点数据源赋值
tree.dataProvider = myData;
2.2 展开所有结点
tree.expandChildrenOf(tree.selectedItem,true);
tree.openItems=[];
2.4 添加子节点
var xml:XML=tree.selectedItem as XML;
xml.appendChild("hello");
tree.dataDescriptor.removeChildAt(tree.selectedItem.parent(),tree.selectedItem,tree.selectedItem.childIndex(),tree.dataProvider);
var selectedNode:XML=tree.selectedItem as XML;
//最初的树型数据
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.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)"/>
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]);
} */
}
//保存分组id,name by叶东林2011-11-29
groupArray = new Array();
//保存uid,name 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]);
} */
}
//保存分组id,name by叶东林2011-11-29
groupArray = new Array();
//保存uid,name 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 格式的数据,我在实现的过程中走了些弯路,我就把我做的东东拿出来讨论。希望对工作和学习有帮助。一起学习,天天进步。
(完,待续 ............... )