XPLATFORM 101
Application > Transaction (FirstRow:CSV)

대용량 데이터를 다루는 것은 RIA를 도입한 취지와 조금은 동떨어진것 같지만
기존 업무 프로세스와의 연계나 어쩔 수 없이 필요한 경우가 생기곤 합니다.
때문에 각 RIA 프레임워크에서는 대용량 데이터를 어떻게 효과적으로 처리할 수 있을지에 대한
고민을 하지 않을 수 없습니다.

FirstRow 라는 방법 역시 이런 고민 중 하나입니다.
하지만 모든 상황에 맞는 정답은 없습니다. 업무를 이해하고 사용자에게 가장 적합한 방법을 선택해야겠죠.

FirstRow는 일종의 트릭과 같습니다. 사용자 입장에서 데이터를 다 가져올때까지 기다리지 않고
일정량의 데이터만 먼저 화면에서 확인하고 나머지를 보완하는 방법입니다.


특별히 다른 설정은 없고 Dataset에서 firefirstcount, firenextcount 를 설정해주면 됩니다.
firefirstcount 의 설명을 보면
FirstRow 형태로 통신할때 첫번째 onload Event를 발생시킬 Count를 지정하는 Property 입니다. 라고 나와있습니다.
지정된 속성값과 일치하는 데이터가 들어왔을때 이벤트가 발생됩니다.

Dataset의 로드 이벤트는 6가지 발생원인을 가지게 됩니다.
DSLoadEventInfo 이벤트에서 reason 속성을 확인할 수 있습니다.
일반적으로는 Dataset.REASON_LOAD (0) 일때 값을 처리하겠지만
FirstRow의 경우에는 Dataset.REASON_LOADPROCESS (1) 일때 값을 처리하게 됩니다.
그리고 마지막 값을 다 가져왔을때 Dataset.REASON_LOAD 값이 떨어지게 됩니다.

firefirstcount 값은 화면에 보여지는 영역에 맞거나 크게 잡아야 겠죠. 그렇지 않으면
데이터가 뚝뚝 끊어지는 느낌을 줄 수 있습니다.

* 그림에도 나와있지만 다른 코드와는 달리 JSP 소스까지 쇼케이스에 포함되어있네요. ^^

http://cafe.naver.com/xplatform101/150 
XPLATFORM 101
Application > Transaction

아마도 기업용 애플리케이션에서 가장 많이 사용하는 기능이 트랜잭션입니다.
데이터를 조회하고 추가, 삭제, 변경 하고 저장하는 일련의 프로세스의 틀을 벗어나지 않습니다.

transaction 은 Dataset의 값을 갱신하기 위한 서비스를 호출하고 transaction이 완료되면 콜백 함수를 수행하는 메소드입니다.

[application.]transaction(strSvcID,strURL,
strInDatasets,strOutDatasets,strArgument,strCallbackFunc[,bAsync[,bBinary[,bCompress]]])

기본적으로 필요한 항목이 많군요.

strSvcID : 트랜잭션을 구별하기 위한 ID
strURL : 요청 주소 값
strInDatasets : 트랜잭션 요청시 입력값으로 보낼 Dataset의 ID의 집합. 1개 이상을 보낼 수 있으며 빈칸으로 구분
strOutDatasets : 처리결과를 받을 Dataset ID. 역시 1개 이상을 받을 수 있음
strArgument : 트랜잭션을 위한 인자값. a=b 형식
strCallbackFunc : 결과를 돌려줄 콜백 함수

그리고 나머지 옵션은

비동기 여부, Binary 여부, 압축 여부를 결정합니다.

- 조회가 어떤 식으로 들어가는지 살펴봅시다.
transaction("select",
"Svc::TransactionSample/select_sample_db.jsp?getvar=테스트test123","","Dataset00=output",vArgument,"fn_callback",bReqAsync,bReqBinary,bReqCompress);

일단 첫번째 인자는 ID 구요.

두번째 인자가 요청 주소값인데 Svc 는 TypeDefinition에서 지정합니다.


그리고 세번째는 최초 조회시에는 필요하지 않기 때문에 빈칸으로 놔두었습니다.
업데이트 처리시에 사용되는 부분이죠.

네번째는 데이터를 받을 Dataset을 지정해주고

다섯번째는 트랜잭션에 필요한 인자값(조건)을 넣어줍니다.
예제에서는 vArgument 라는 변수로 따로 지정을 했구요.
해당 값은 XML로 전달되는 경우에는 다음과 같이 전달됩니다.
vArgument = "arg="+encodeURI("한글testArg") +  " bResType=" + Combo01.value;
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Parameters>
<Parameter id="JSESSIONID" type="STRING">5D5B9FBEA8F277EE75E9ED9579D66841</Parameter>
<Parameter id="arg" type="STRING">%ED%95%9C%EA%B8%80testArg</Parameter>
<Parameter id="bResType" type="STRING">xml</Parameter>
</Parameters>
</Root>
넘어오는 데이터를 살펴보면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns="http://www.tobesoft.com/platform/dataset" ver="5000">
<Parameters>
<Parameter id="ErrorCode" type="int">0</Parameter>
<Parameter id="ErrorMsg" type="string">SUCC</Parameter>
</Parameters>
<Dataset id="output">
<ColumnInfo>
<Column id="no" type="int" size="4"/>
<Column id="id" type="string" size="12"/>
<Column id="name" type="string" size="50"/>
<Column id="sid" type="string" size="13"/>
<Column id="password" type="string" size="50"/>
<Column id="email" type="string" size="50"/>
<Column id="address1" type="string" size="100"/>
<Column id="address2" type="string" size="100"/>
<Column id="post" type="string" size="100"/>
<Column id="phone1" type="string" size="50"/>
<Column id="phone2" type="string" size="50"/>
<Column id="officeNm" type="string" size="50"/>
</ColumnInfo>
<Rows>
<Row>
<Col id="no">1</Col>
<Col id="id">hunnam</Col>
<Col id="name">홍길순</Col>
<Col id="sid">8107221234567</Col>
<Col id="password">1234</Col>
<Col id="email">leehm@tobesoft.com</Col>
<Col id="address1">서울시&#32;송파구&#32;잠실동</Col>
<Col id="address2">222번지&#32;서일빌딩&#32;7층</Col>
<Col id="post">138-863</Col>
<Col id="phone1">01036475643</Col>
<Col id="phone2">0221407112</Col>
<Col id="officeNm">투비소프트</Col>
</Row>
<Row>
<Col id="no">2</Col>
<Col id="id">hunnam</Col>
<Col id="name">홍길동</Col>
<Col id="sid">9312032031020</Col>
<Col id="password">345678</Col>
<Col id="email">hgd@naver.com</Col>
<Col id="address1">서울</Col>
<Col id="address2">삼성역</Col>
<Col id="post">123-456</Col>
<Col id="phone1">01012345671</Col>
<Col id="phone2">022123456</Col>
<Col id="officeNm">디자인회사</Col>
</Row>
</Rows>
</Dataset>
</Root>
기본 옵션 외의 나머지를 보면 쇼케이스에서 테스트하는 부분이 바이너리 유무와 압축 유무입니다.

기본 옵션과 바이너리, 바이너리 압축을 비교해보면 위의 데이터의 경우 물리적인 크기의 차이가 있긴 합니다.


하지만 바이너리 변환과 압축과정에서의 손실이 있으며 헤더값이 추가적인 정보가 들어가기 때문에
상황에 따라 어떤 형식을 선택할지 고려해야 합니다.

삭제나 추가는 Dataset에 직접 deleteRow()나 addRow()를 사용합니다.
addRow()일 경우에는 성공시 해당하는 Row의 위치값을 반환해주기때문에
바로 Dataset.setColumn() 메소드로 해당하는 값을 설정해줍니다.

저장시에는 아래와 같은 형식으로 업데이트될 Dataset을 데이터를 보내줍니다.
달라지는 부분은 <Row type="insert"> 으로 처리되는 부분이네요.
delete 는 삭제, update 는 수정, insert 는 추가입니다.
update 일 경우에는 OrgRow 라는 항목이 추가됩니다.
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Parameters>
<Parameter id="GID" type="STRING"></Parameter>
<Parameter id="NEIS" type="STRING"></Parameter>
<Parameter id="JESSIONID" type="STRING"></Parameter>
<Parameter id="JSESSIONID" type="STRING">597FB296B292335D787A54EC766B815A</Parameter>
<Parameter id="arg" type="STRING">%ED%95%9C%EA%B8%80testArg</Parameter>
<Parameter id="bResType" type="STRING">xml</Parameter>
</Parameters>
<Dataset id="input">
<ColumnInfo>
<Column id="no" type="INT" size="4"/>
<Column id="id" type="STRING" size="12"/>
<Column id="name" type="STRING" size="50"/>
<Column id="sid" type="STRING" size="13"/>
<Column id="password" type="STRING" size="50"/>
<Column id="email" type="STRING" size="50"/>
<Column id="address1" type="STRING" size="100"/>
<Column id="address2" type="STRING" size="100"/>
<Column id="post" type="STRING" size="100"/>
<Column id="phone1" type="STRING" size="50"/>
<Column id="phone2" type="STRING" size="50"/>
<Column id="officeNm" type="STRING" size="50"/>
</ColumnInfo>
<Rows>
<Row type="delete">
<Col id="no">1</Col>
<Col id="id">hunnam</Col>
<Col id="name">홍길순</Col>
<Col id="sid">8107221234567</Col>
<Col id="password">1234</Col>
<Col id="email">leehm@tobesoft.com</Col>
<Col id="address1">서울시&#32;송파구&#32;잠실동</Col>
<Col id="address2">222번지&#32;서일빌딩&#32;7층</Col>
<Col id="post">138-863</Col>
<Col id="phone1">01036475643</Col>
<Col id="phone2">0221407112</Col>
<Col id="officeNm">투비소프트</Col>
</Row>
<Row type="update">
<Col id="no">2</Col>
<Col id="id">hunnam</Col>
<Col id="name">홍길동</Col>
<Col id="sid">9312032031020</Col>
<Col id="password">345678</Col>
<Col id="email">hgd@naver.com</Col>
<Col id="address1">성남</Col>
<Col id="address2">삼성역</Col>
<Col id="post">123-456</Col>
<Col id="phone1">01012345671</Col>
<Col id="phone2">022123456</Col>
<Col id="officeNm">디자인회사</Col>
<OrgRow>
<Col id="no">2</Col>
<Col id="id">hunnam</Col>
<Col id="name">홍길동</Col>
<Col id="sid">9312032031020</Col>
<Col id="password">345678</Col>
<Col id="email">hgd@naver.com</Col>
<Col id="address1">서울</Col>
<Col id="address2">삼성역</Col>
<Col id="post">123-456</Col>
<Col id="phone1">01012345671</Col>
<Col id="phone2">022123456</Col>
<Col id="officeNm">디자인회사</Col>
</OrgRow>
</Row>
<Row type="insert">
<Col id="no">3</Col>
<Col id="id">test</Col>
<Col id="name">test</Col>
<Col id="sid">1111111</Col>
<Col id="password">1111</Col>
<Col id="email">111@111</Col>
<Col id="address1">11</Col>
<Col id="address2">11</Col>
<Col id="post">11</Col>
</Row>
</Rows>
</Dataset>
</Root>
* 대용량 데이터 조회(FirstRow)에 대해서는 따로 다루도록 하겠습니다.
* 생각보다 설명할 내용이 길어지네요. ㅠㅠ

http://cafe.naver.com/xplatform101/149 
XPLATFORM 101
순서대로 진행합니다.
몇몇 내용은 앞에서 다룬 부분이 있기 때문에 중복된 내용은 링크로 처리합니다.

Application > Application Message
: 예전에는 거의 대부분 Alert 을 많이 사용했는데 최근에는 사용자 동선에 방해되지 않게
메시지의 중요도에 따라 처리해주는 경향입니다.
여기서 다루는 것은 기능에 대한 이야기니깐 어떨때 어떻게 사용해야 한다는 것은
각 프로세스에 따라 달라질겁니다.

(1) alert
- 뭐 워낙 많이 다룬 내용이니깐..

(2) confirm
- alert 과 비슷하지만 사용자의 확인을 받는다는 점이 다릅니다.
엑스플랫폼 메뉴얼에는 confirm 메소드를 실행하는 경우 보여지는 대화상자라고 설명하고 있네요.
2개의 버튼을 가지고 있습니다. 
- 쇼케이스를 보면 특이하게 alert 안에 confirm 을 사용하고 있습니다.
function Button01_onclick(obj:Button,  e:ClickEventInfo)
{
alert(confirm( "확인" ));
}
이렇게 되면 confirm 에서 나온 리턴값을 alert 으로 보여주게 됩니다.
쉽게 풀어주면
var result = confirm("확인");
alert(result);
와 동일한 내용입니다.

alert 과 마찬가지로 confirm과 Confirm 은 다릅니다. ^^


(3) showModeless
(4) showModal
- 일단 modal 의 개념부터 알아야 할듯 합니다.
Modal Dialog : 사용자의 입력이 들어오기 전까지 메인 윈도우가 새로운 메시지를 처리하지 못하게 하는 대화상자
Modeless Dialog : 대화상자에 입력이 없어도 메인 윈도우에 포커스를 이동해서 프로세스를 진행할 수 있는 대화상자

* Modaless가 아니라 Modeless 가 맞는 표현입니다.


- 엑스플랫폼에서는 동적으로 생성된 자식프레임을 보여주는 방식으로
다음과 같이 4가지를 제안하고 있습니다.

ChildFrame.show()
: 그냥 보여주는 겁니다. show() 메소드가 호출되고 나서 ChildFrame 의 formurl을 로딩하게 됩니다.
물론 동적으로 생성하기 때문에 OwnerFrame에 add나 insert 를 먼저 해야겠죠.
ChildFrame.showModal(objParentFrame, [{objArgumentList}[, objOpener]])
: 이것은 대화상자 형식으로 보여줍니다. 우리가 일반적으로 이야기하는 팝업과 같은 형식이 되겠죠.
show()와는 달리 별도로 OwnerFrame에 포함시키지 않아도 자동으로 추가되고 창을 닫게 되면
목록에서 사라지게 됩니다.
ChildFrame.showModalAsync(objParentFrame, [{objArgumentList}][,objOpener][,callbackFunc]);
: showModel()과 동일하지만 한가지 중요한 차이가 showModalAsync()가 호출되고 나서 나머지 스크립트가 실행된다는 겁니다. 그리고 callback함수를 선언할 수 있어 결과값을 처리할 수 있습니다.
로딩 애니메이션같은 화면을 구현할때 적절하지 않을까 싶네요.
ChildFrame.showModeless(objParentFrame,[{objArgumentList}[, objOpener]]);
: 포커스가 이동되는 것만이 아니라 showModalAsync와 마찬가지로 호출 이후 나머지 스크립트가 실행됩니다.

objNew.showModal("showModal", objOwnerFrame);
trace('test');

위와 같은 예제의 경우에는 trace가 창을 닫기 전까지 실행되지 않습니다.

http://cafe.naver.com/xplatform101/148