동작은 아직 미비한 편이지만 http://blog.jidolstar.com/18 에서 만든 것에 기능을 개선시켰다.
개선된 기능은 다음과 같다.
- 전체펼치기/접기 기능 추가
- 선택된 노드 펼치기/접기 기능추가
- 찾을 노드 id를 입력하여 해당 노드를 펼치고 선택하기 기능 추가
프로그램은 아직 실용성은 없으며 계속 보완해가고 있는 중이다. 최종 결과물은 각 노드의 위치를 바꾸고 서버에 비동기적으로 통신하여 수정할 수 있게 만들어갈 예정이다.
사용한 XML 파일은 다음과 같다.
<?xml version="1.0" encoding="utf-8" ?>
<root>
<msg>ok</msg>
<nodes>
<node id="a" label="홈">
<node id="b-1" label="제품">
<node id="c-1" label="플렉스" />
<node id="c-2" label="플래시" />
</node>
<node id="b-2" label="도움말">
<node id="c-3" label="플렉스 라이브 문서" />
<node id="c-4" label="플래시 라이브 문서" />
</node>
<node id="b-3" label="커뮤니티">
<node id="c-5" label="플렉스 커뮤니티">
<node id="d-1" label="플렉스컴포넌트 카페" />
<node id="d-2" label="어도비유저그룹" />
</node>
<node id="c-6" label="플래시 커뮤니티" />
</node>
</node>
</nodes>
</root>
파일명 : TreeTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml " layout="absolute"
initialize="System.useCodePage=true"
xmlns:js="com.jidolstar.components.*" creationComplete="init()">
<mx:Script>
<![CDATA[
private function init():void
{
myTreeXMLMenu.setCrossDomain("crossdomain.xml 파일 url");
myTreeXMLMenu.request("XML파일 url");
}
]]>
</mx:Script>
<mx:Style>
Application
{
fontSize:12pt;
}
</mx:Style>
<mx:Panel width="500" height="300"
layout="absolute" title="동적으로 바인드되는 XML Tree 메뉴+Node찾아펼치기-jidolstar.com">
<mx:VBox width="100%" height="100%">
<js:TreeXMLMenu id="myTreeXMLMenu" width="100%"/>
<mx:HBox>
<mx:Label text="찾을 노드 ID"/>
<mx:TextInput width="100" id="findValue" text="d-2"/>
<mx:Button label="찾기" click="myTreeXMLMenu.find(findValue.text)"/>
</mx:HBox>
<mx:HBox>
<mx:Button label="전체펼치기" click="myTreeXMLMenu.expandAll(true)"/>
<mx:Button label="전체접기" click="myTreeXMLMenu.expandAll(false)"/>
<mx:Button label="선택된노트 접기/펼치기" click="myTreeXMLMenu.expand()"/>
</mx:HBox>
</mx:VBox>
</mx:Panel>
</mx:Application>
파일명 : com.jidolstar.componet.TreeXMLMenu.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Tree xmlns:mx="http://www.adobe.com/2006/mxml "
labelField="@label"
dataProvider="{xlcData}"
showRoot="false" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.*;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
import flash.system.Security;
public var httpServ:HTTPService;
[Bindable]
public var xlcData:XMLListCollection;
////////////////////////////////////////////
// 초기화
// HTTPSerivce를 생성
////////////////////////////////////////////
public function init():void
{
httpServ = new HTTPService();
}
////////////////////////////////////////////
// CrossDomain 설정
////////////////////////////////////////////
public function setCrossDomain(url:String):void
{
Security.loadPolicyFile(url);
}
////////////////////////////////////////////
// XML 요청
// 1. POST방식으로 요청하고 결과물을 E4X형태로 한다.
// 2. 결과를 받기 위해 Listener Handler함수를 선언
////////////////////////////////////////////
public function request(url:String , params:Object=null):void
{
this.httpServ.url = url;
this.httpServ.method = "POST";
this.httpServ.resultFormat="e4x";
this.httpServ.addEventListener("result", resultHandler);
this.httpServ.addEventListener("fault", faultHandler);
this.httpServ.send(params);
}////////////////////////////////////////////
// XML 결과를 받았을 경우
// 1. XMLList에 결과를 임시로 저장
// 2. 적합한 데이타인지 확인
// 3. nodes요소만 XMLListCollection으로 생성
// 이는 동적으로 Tree에 바인드[Bindable]됨
////////////////////////////////////////////
private function resultHandler(e:ResultEvent):void
{
var xlData:XMLList = new XMLList(e.result);
if(xlData.elements("msg").toString()!="ok")
{
mx.controls.Alert.show(xlData.elements("msg").toString(),"Error");
}
else
{
xlcData = new XMLListCollection(xlData.elements("nodes"));
}
}
////////////////////////////////////////////
// XML 데이타 요청에 대한 실패가 있을 경우 호출됨
////////////////////////////////////////////
private function faultHandler(e:FaultEvent):void
{
mx.controls.Alert.show("XML정보 읽어오기 실패\n"+e.fault.faultString);
}
////////////////////////////////////////////
// Tree 전체를 접고 펼침
////////////////////////////////////////////
public function expandAll(open:Boolean):void
{
var xlc:XMLListCollection = this.dataProvider as XMLListCollection;
var nodeList:XMLList = xlc.descendants();
trace(nodeList.length());
for(var i:int=0; i<nodeList.length(); i++)
{
trace(nodeList[i]);
this.expandItem(nodeList[i], open, false);
}
}
////////////////////////////////////////////
// 선택한 Node 접고 펼침
////////////////////////////////////////////
public function expand():void
{
var selectedNode:Object=this.selectedItem;
trace(selectedNode);
if(this.isItemOpen(selectedNode)==true)
{
this.expandItem(selectedNode, false);
trace("close");
}
else
{
this.expandItem(selectedNode, true);
trace("open");
}
}
////////////////////////////////////////////
// 인자로 넘어온 id값을 찾는다.
////////////////////////////////////////////
public function find(id:String):Boolean
{
var xlc:XMLListCollection = this.dataProvider as XMLListCollection;
var nodeList:XMLList = xlc.descendants();
trace(nodeList.length());
for(var i:int=0; i<nodeList.length(); i++)
{
trace(nodeList[i].@id.toString());
if(nodeList[i].@id.toString() == id)
{
trace(i);
break;
}
}
if(i == nodeList.length())
{
trace("id='"+id+"'는 없음");
return false;
}
expandParents(nodeList[i]);
this.selectedItem = nodeList[i];
return true;
}
////////////////////////////////////////////
// 인자로 넘어온 node의 부모를 전부 펼친다.
////////////////////////////////////////////
protected function expandParents(xmlNode:XML):void
{
if(xmlNode == null)
{
return;
}
while (xmlNode.parent() != null && xmlNode.localName().toString() == "node")
{
xmlNode = xmlNode.parent();
this.expandItem(xmlNode, true, false);
}
}]]>
</mx:Script>
</mx:Tree>
글쓴이 : 지돌스타 (http://blog.jidolstar.com/18 )