[Flex]동적으로 바인드되는 XML Tree 메뉴+Node찾아펼치기
[공지]이미지나 링크가 깨졌다면 댓글 부탁드립니다.
동작은 아직 미비한 편이지만 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 )
'Adobe Flash Platform' 카테고리의 다른 글
| Flex Demo 및 Source 링크 (0) | 2007/05/23 |
|---|---|
| Flex 프로젝트 문서화 - ASDoc 사용하기 (6) | 2007/05/22 |
| Flex Builder 에서 Subversion(SVN) 사용하기 (6) | 2007/05/21 |
| Flex 관련 링크 모음-시난님 작성 (0) | 2007/05/16 |
| [Flex]동적으로 바인드되는 XML Tree 메뉴+Node찾아펼치기 (11) | 2007/04/11 |
| [Flex]XML데이타를 Tree에 동적바인드 (2) | 2007/04/11 |
-
2007/04/11 19:11[Flex]XML데이타를 Tree에 동적바인드 Tracked from 지돌스타 블로그



category.xml

crossdomain.xml은 도데체 어떻게 사용하는걸까? ㅋㅋㅋ
Error: Unknown Property: '-1'.
at mx.collections::ListCollectionView/http://www.adobe.com/2006/actionscript/flash/proxy::getProperty()
at mx.controls.treeClasses::HierarchicalViewCursor/get current()
at mx.controls.treeClasses::HierarchicalViewCursor/collectionChangeHandler()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.controls::Tree/http://www.adobe.com/2006/flex/mx/internal::onTweenEnd()
at mx.effects::Tween/endTween()
at mx.controls::Tree/mx.controls:Tree::updateDisplayList()
at mx.core::UIComponent/validateDisplayList()
at mx.managers::LayoutManager/::validateDisplayList()
at mx.managers::LayoutManager/::doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/::callLaterDispatcher2()
at mx.core::UIComponent/::callLaterDispatcher()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.controls::Tree/http://www.adobe.com/2006/flex/mx/internal::onTweenEnd()
at mx.effects::Tween/endTween()
at mx.effects::Tween/http://www.adobe.com/2006/flex/mx/internal::doInterval()
at mx.effects::Tween$/::timerHandler()
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()
버그 올려주신 것 감사합니다. 그런데... 저도 정확한 이유는 잘 모르겠지만...
this.selectedItem = nodeList[i]; 이부분을 주석처리 하면 더이상 버그가 없더군요.
이것은 해당 node를 찾은뒤에 그 node를 선택하게 할려고 하는 것인데...
이상하게 이 동작을 한 뒤에 전체펼치기 접기를 하다보면 에러가 나는군요.
트리컴포넌트.selectedItem = -1 일때 나는 오류 입니다.
selectedItem 이 -1인 것은 선택된 항목이 없다는 얘기구요...
앞뒤 구문을 안봐서 모르겠지만...
if(nodeList[i]!=-1) { this.selectedItem=nodeList[i]; } 요렇게 하면 안날것 같은걸요?
ㅎㅎㅎ
그러게요~
고맙습니다. ^^
부족한 실력인지라 언제나 도움만 받네요. 좋은 자료 늘 감사할 따름입니다. 한가지 의견을 드리자면, 찾을 노드에 값을 입력하고 버튼을 누르면 트리가 길어질 경우 어디로 찾아갔는지 화면상에 보이지 않아 스크롤바를 눌러 찾는 불편이 있네요.
자동으로 스크롤바 위치까지 조정하여 해당 노드로 스크롤 바를 위치시키는 기능을 추가하면 어떨까요?
네~ 정말 그렇겠네요. 의견감사합니다.
저도 사용중에 스크롤 찾는 부분이 필요해서 추가했는데
if(this.verticalScrollPosition != 0)
verticalFocus = this.verticalScrollPosition;
this.verticalScrollPosition = verticalFocus;
포커스 잡는 함수에 추가했어용^^
네~~~ 좋은 코드 감사합니당.
데이터 바인딩과 동시에(?) 전체펼치기가 이루어지게 하기 위해서
(즉, 처음부터 전체 펼치기 모드로 트리를 보여주고 싶을때)
updateComplete속성을 이용해서 두번째 이에 해당하는 함수가 호출되었을 때 다음과 같이 해줘야 전체 펼치기가 가능했습니다.
this.expandChildrenOf(selectedNode, true);
+ 지돌스타님 블로그에서 많은 도움을 얻었기 때문에 혹시나 필요로 하실 분들을 위해 제가 추가로 구현한 것들을 팁으로 남깁니다 ^ ^ 도움이 되시길....
감사합니다. ^^