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 |