Tech/Flex

6 컨트롤에서 리모트 XML 데이터 사용하기

onesixx 2009. 3. 13. 14:50
반응형

HTTPSevice 클래스를 통해 원격웹서버에 Request를 던지고

응답된 xml 데이터를 (Flex내에서 다루기 쉽도록) ArrayCollection, xmlListCollection을 사용하여 보관하고

Data Provider (콤보, 리스트 컨트롤,Tree컨트롤 …)에 연결하여 출력

 

HTTPService에서 XML 데이터 검색하기

 

객체생성

1. <mx:HTTPService

2. Actionscript로 직접 객체생성
    New …

 

----------------------

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" creationComplete="unitRPC.send();">

 

<mx:Script>
    <![CDATA[
        private function unitRPCResult(event:ResultEvent):void{
            trace(event.result.allUnits.unit[2].unitName);
            trace(event.result.allUnits.unit[2].unitID);
        }
    ]]>
</mx:Script>
    <mx:HTTPService id="unitRPC" url="http://www.flexgrocer.com/units.xml"
                    result="unitRPCResult(event);"/>

---------------------

 

HTTPService 데이터를 ArrayCollection으로 채우기

배열보다는 ArrayCollection사용 – 장점 : sorting filtering

각각xml에 태그에 대해 객체를 만든다.

    <![CDATA[

        import mx.collections.ArrayCollection;
        [Bindable]
        private var units:ArrayCollection;
        private function unitRPCResult(event:ResultEvent):void{
            units = event.result.allUnits.unit;

/*          trace(event.result.allUnits.unit[2].unitName);
            trace(event.result.allUnits.unit[2].unitID); */


        }
    ]]>

 

<mx:HTTPService id="unitRPC" url="http://www.flexgrocer.com/units.xml"  result="unitRPCResult(event);"/>

<mx:FormItem label="Unit">
      <mx:List id="unitID" rowCount="4" dataProvider="{units}"   labelField="unitName"/>
</mx:FormItem>

 

콤보박스 컨트롤 아이템(All) 추가하기

 

<mx:Script>
    <![CDATA[
        import mx.rpc.events.ResultEvent;
        import mx.collections.ArrayCollection;


        [Bindable]
        private var categories:ArrayCollection;


        private function catHandler(event:ResultEvent):void{
            categories = event.result.catalog.category;
            var catObj:Object = new Object();


          catObj.name = "All";
          catObj.categoryID = 0;


            categories.addItemAt(catObj,0);
            catCombo.selectedIndex = 0;   //재Sorting
        }
    ]]>
</mx:Script>

 

Tree 컨트롤에 XML 데이터 사용하기

E4X (ECMAScript for XML)
ActionScript3.0도 ECMA Script Spec에 기반하여 만들어 짐.

E4X Expression (XML에서 Query하는 방법)

category.product

category.product[2]

조건

- Child Element : category.product.(unit=="bag")

                       category.product.(@cost>2)

- 속성 : category.product.(@cost=="1.95")

- 복합조건: category.product.(@cost=="1.95").(unit=="each")

 

- descendant Element: category..product

 

XML데이터로 Tree 컨트롤 채우기

 

resultFormat=”array” –> event.result.[root element].[child.element]

resultFormat=”e4x” –> event.result.[child.element]

-------------------------------------------

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" creationComplete="prodByCatRPC.send()">

<mx:Script>
    <![CDATA[

        [Bindable]
        private var foodColl:XMLList
        private function prodByCatRPCResult(event:ResultEvent):void{
            foodColl = event.result.category;
        }
    ]]>

<mx:HTTPService id="prodByCatRPC" url="http://www.flexgrocer.com/categorizedProducts.xml"
                   resultFormat="e4x"   result="prodByCatRPCResult(event);"/>

 

<mx:Tree id="productTree"  height="100%"  dataProvider="{foodColl}" labelField="@name"/>

 

--간결하게-->>

 

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" creationComplete="prodByCatRPC.send()">

<mx:HTTPService id="prodByCatRPC" url="http://www.flexgrocer.com/categorizedProducts.xml"
                    resultFormat="e4x"/>
<mx:XMLListCollection id="foodColl" source="{prodByCatRPC.lastResult.category}"/>

<mx:Tree id="productTree"  height="100%" dataProvider="{foodColl}" labelField="@name"/>

 

 

* addEventListener를 호출해서 이벤트이름과 호출될 메소드이름을 넘겨줘야 함

  --> MXML에서 ActionScript 코드를 작성하게 되면, Event에서 호출될 메소드를  자동으로 만들어 

   작성된 ActionScript를 카피해서 넣는다.

event.target은 트리객체의 주소가 리턴된다.

<mx:Script>
    <![CDATA[

        import utils.Util;


        private function populateForm(event:Event):void{
            //trace("OKOK");
            var selectedNode:Object = event.target.selectedItem;
            //race(selectedNode.@prodName);
            if (selectedNode.@prodName != undefined) {
                prodName.text= selectedNode.@prodName;
                Util.presetList(unitID,"unitID",selectedNode.@unitID);
                cost.text            = selectedNode.@cost;
                listPrice.text       = selectedNode.@listPrice;
                description.text     = selectedNode.@description;
                isLowFat.selected    = Util.yesNoToBoolean(selectedNode.@isLowFat);
                isOrganic.selected   = Util.yesNoToBoolean(selectedNode.@isOrganic);
                imageName.text       = selectedNode.@imageName;               
            }else{
                prodName.text        ="";
                unitID.selectedIndex = -1;
                cost.text            ="";
                listPrice.text       ="";
                description.text     ="";
                isLowFat.selected    =false;
                isOrganic.selected   =false;
                imageName.text       ="";
            }
        }
    ]]>
</mx:Script>

 

<mx:Tree id="productTree"  height="100%" dataProvider="{foodColl}" labelField="@name"
             change="populateForm(event);"/>

 

 

XML 데이터 검색하기 &
XML 데이터를 사용자 정의 객체로 이루어진 ArrayCollection으로 변환하기

 

XML 데이터를 Http서비스를 통해서 가져오면 디폴트로 ArrayCollection를 으로 만들어지고,

이를 Product이라는 클래스(==> ValueObject, DTO) 의 인스턴스로 바꾸자.

 

//creationComplete이벤트 발생시 HttpSevice의 send() 메소드 호출”

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="proByCatRPC.send();">

// HttpService를 통해 Xml데이터를 가져오라고 요청하고, 서버로부터 응답이 오면 자동으로 result이벤트 가 발생하고,
내부적으로 result이벤트에 대해서 호출될 메소드가 자동으로 만들어 지고 그 메소드내에 prodHandler(event); 그대로 삽입됨
event는 자동으로 만들어진 function의 파라미터임.

<mx:HTTPService id="prodByCatRPC" url="http://www.flexgrocer.com/categorizedProducts.xml"
                resultFormat="e4x" result="prodHandler(event);"/>

<mx:Script>
    <![CDATA[

import mx.rpc.events.ResultEvent;
[Bindable]
private var theProduct:Product;

private function prodHandler(event:ResultEvent):void
{
    /* trace(event.result); */
    var prodArray:Array = new Array();
    for each(var p:XML in event.result..product){
        var prod:Product = new Product(
                                        Number(p.@catID),
                                        String(p.@prodName),
                                        Number(p.unitID),
                                        Number(p.@cost),
                                        Number(p.@listprice),
                                        String(p.@description),
                                        Boolean(p.@isLowFat=="Yes"),
                                        Boolean(p.@isLowFat=="yes"),
                                        String(p.@imagename)
                                        );
        prodArray.push(prod);       
    }
    trace(prodArray);
}

    ]]>
</mx:Script>

 

복합 데이터 구조에 대한 데이터 바인딩 사용하기

Array는 bindable하지 않으므로  bindable한 ArrayCollection을 이용함.

import mx.collections.ArrayCollection;           
[Bindable]
private var groceryInventory:ArrayCollection;

private function prodHandler(event:ResultEvent):void
{
    /* trace(event.result); */
    var prodArray:Array = new Array();
    for each(var p:XML in event.result..product){
        var prod:Product = new Product(
                                        Number(p.@catID),
                                        String(p.@prodName),
                                        Number(p.unitID),
                                        Number(p.@cost),
                                        Number(p.@listPrice),
                                        String(p.@description),
                                        Boolean(p.@isOrganic=="Yes"),
                                        Boolean(p.@isLowFat=="Yes"),
                                        String(p.@imageName)
                                        );
       prodArray.push(prod);       
    }
    groceryInventory = new ArrayCollection(prodArray);
}

 

<mx:Label text="{groceryInventory.getItemAt(0).prodName}" id="prodName"/>
            <mx:Image source="{'assets/'+ groceryInventory.getItemAt(0).imageName}"
                                     scaleContent="true"                
                                     mouseOver="this.currentState='expanded'"
                                     mouseOut="this.currentState=''"/>
            <mx:Label text="{groceryInventory.getItemAt(0).listPrice}" id="price"/>
            <mx:Button id="add" label="Add To Cart"
                click="addToCart(groceryInventory.getItemAt(0) as Product)"/>

 

===>

 

 

쇼핑 카트 데이터 조작하기

* 추가

[Bindable]
public var cart:ShoppingCart = new ShoppingCart();

<mx:List id="cartView" dataProvider="{cart.aItems}"/>

-----------------------

<mx:Button id="add" label="Add To Cart"
                click="addToCart(groceryInventory.getItemAt(0) as Product)"/>

----------------------

* ShoppingCart.as

package valueObjects
{
    import flash.utils.*;
    import mx.collections.ArrayCollection;
    public class ShoppingCart
    {
        [Bindable]
        public var aItems:ArrayCollection = new ArrayCollection();


        [Bindable]
        public var total:Number=0;


        public function addItem(item:ShoppingCartItem):void{
            aItems.addItem(item);
        }
    }

 

*정렬

package valueObjects
{
    import mx.collections.Sort;
    import mx.collections.SortField;
  

    public class ShoppingCart
    {

        private function sortItems():void{
            var prodSort:Sort = new Sort();


            var sortField:SortField = new SortField("product");
            var sortField2:SortField = new SortField("quantity");
            prodSort.fields = new Array(sortField, sortField2);


            aItems.sort = prodSort;
            aItems.refresh();
        }
    }
}

 

*ITem 추가/ 수량 변경

 

 

 

 

\\

p158 4번

 

 

삭제 버튼 추가하기

 

--------------------------------------------------------------------------------------------

For Each문

For Each문은 콜렉션이나 배열 안에 있는 문자열을 찾거나 문자열 항목을 알아 내고자 할 때 사용합니다.

<?xml:namespace prefix = o />

                     For Each 구성요소 In 그룹명
                     [문장]
                     [Exit For]
                     [문장]
                     Next [구성요소]

[그룹명]은 배열이나 컬렉션(Collection)을 설정할 수 있고
[구성요소]에는 그룹명의 내용을 넣을 수 있도록 Variant형식 또는 객체(Object)형식으로 설정을 합니다.

For Each 다음에 있는 [구성요소]와 Next 다음에 있는 [구성요소]는 동일해야 합니다.
For Each문은 [그룹명]에 들어 있는 문자열만큼 반복을 하면서 [구성요소]에 그 문자열 값을 전달합니다.
그렇기 때문에 그룹명안에 있는 문자열을 찾거나 비교하려면 [구성요소]를 이용합니다.

[실습] 리스트박스에서 이름찾기

이 프로그램은 For Each문을 어떻게 사용하는 지를 알 수 있는 예제입니다.


' 컬렉션 선언
Dim C_Name As New Collection

' 폼의 Load이벤트
Private Sub Form_Load()
Dim i As Integer

' 리스트박스에 문자열을 추가
List1.AddItem "신문섭"
List1.AddItem "김정주"
List1.AddItem "송준규"
List1.AddItem "황용문"
List1.AddItem "나성만"
List1.AddItem "이승훈"

' 리스트 박스 안에 있는 문자열을 콜렉션에 넣습니다.
For i = 0 To 5
C_Name.Add List1.List(i)
Next

End Sub

' 명령버튼의 Click이벤트
Private Sub Command1_Click()
Dim My_Find

' 텍스트박스에서 입력한 문자열이 컬렉션 안에 포함된 문자열과'  같은 것이 있는지를 찾습니다.
For Each My_Find In C_Name
If My_Find = Text1.Text Then
   Label1.Caption = Text1.Text + "을(를) 찾았습니다."
   Exit For
Else
  Label1.Caption = Text1.Text + "을(를) 못 찾았습니다."
End If
Next

End Sub

프로시저밖에 있는 선언은 'Dim C_Name As New Collection'는 폼에 있는 프로시저에서 사용할 수 있게 하기 위해서입니다. 만약, 다음과 같이 선언한다면 Form_Load()프로시저 안에서만 사용할 수 있습니다.

Private Sub Form_Load()
Dim C_Name As New Collection
   .    
   .
End Sub

New키워드를 이용하여 콜렉션을 참조할 수 있게 해줍니다.
리스트박스(List1) 컨트롤에 항목을 추가하려면, AddItem 메서드를 이용하여 문자열을 추가할 수 있습니다. 추가된 항목의 인덱스(Index)번호는 0부터 시작하여 추가할 때 마다 1씩 증가하여 들어 갑니다.
List속성은 리스트박스 컨트롤에 들어간 항목의 인덱스 번호를 이용하여 문자열을 알아낼 수 있습니다. 예를 들면, 첫 번째에 추가한 '신문섭'은 인덱스 번호가 0번이므로 List(1)하면 알아낼 수 있습니다.
다음과 같이 For문을 사용하여 리스트박스 컨트롤에 들어있는 문자열을 콜렉션에 저장할 수 있습니다.

For i = 0 To 5
C_Name.Add List1.List(i)
Next

텍스트박스(Text1)에서 입력한 문자열과 동일한 문자열을 콜렉션에서 찾고자 한다면, 다음과 같이 For Each문을 사용한 뒤 My_Find 변수와 같은지를 비교하여 알아내면 됩니다.

For Each My_Find In C_Name
If My_Find = Text1.Text Then
   Label1.Caption = Text1.Text + "을(를) 찾았습니다."
   Exit For
Else
  Label1.Caption = Text1.Text + "을(를) 못 찾았습니다."
End If
Next


[실행 화면]

실행한 후에 '이승훈'을 입력합니다.그런 다음 [찾기]버튼을 누르면 다음과 같이 나타납니다.

리스트에 없는 '이우동'을 입력한 후 [찾기]버튼을 누르면 '못 찾았습니다.' 메시지가 출력됩니다.

[출처]

문법과 데이터형 - For Each문 (소스/프로그램개발) |작성자 happyboy719

반응형

'Tech > Flex' 카테고리의 다른 글

7 MXML로 컴포넌트 만들기  (0) 2009.04.06
5 이벤트 핸들링과 데이터 구조  (0) 2009.03.12
FLEX Yahoo API 사용방법  (3) 2009.03.12
4. 컨트롤 사용하기  (0) 2009.03.11
3. Flex - Interface Layout  (0) 2009.03.03
2. Flex 시작하기  (0) 2009.03.03