")


위의 소스는 FlexComponent 카페에서 시난님이 만든 "XML의 자식을 가지고 있는 마지막 노드 알아내기(http://cafe.naver.com/flexcomponent/3755)" 글을 보고 아이디어를 얻었다. 시난님이 이것을 만들게 된 계기는 카페 주인장이신 브라이언 님이 WithFlex.com에서 운영할 Flex로 만든 트리메뉴를 같이 만들자고 제안을 했기 때문이다. 그렇지 않아도 Tree메뉴가 필요할 것 같아서 만들려고 하던 참이였는데 동지를 만난것 같아 넘 좋다.

동작은 아직 미비한 편이지만 http://blog.jidolstar.com/18 에서 만든 것에 기능을 개선시켰다.
개선된 기능은 다음과 같다.


  1. 전체펼치기/접기 기능 추가
  2. 선택된 노드 펼치기/접기 기능추가
  3. 찾을 노드 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>

           
프로그램 소스는 http://blog.jidolstar.com/18 에서 올린 것과 다르게 Tree를 상속받아서 사용했다. 나중에 나만의 컴퍼넌트를 만들어 아무때나 사용하기 위해서이다.

파일명 : 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  )
신고
Posted by 나비 나비:D

BLOG main image
by 나비:D

공지사항

카테고리

분류 전체보기 (278)
Programming? (0)
----------------------------- (0)
나비의삽질 (5)
Application (177)
SQL (51)
Web (27)
etc. (14)
Omnia (0)
---------------------------.. (0)

글 보관함

달력

«   2017/10   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Total : 882,507
Today : 3 Yesterday : 218