[scrap]DataGridColumn을 확장한 DataGrid 개발(formatter 적용)

Programming/Flex 2009.02.24 11:36
본 자료는 최용범님께서 2008년 8월에 아래 사이트게 작성한 내용을 스크랩한 것입니다.
http://www.adobeflex.co.kr/iwt/board/board.php?tn=pds_tech&bc=4&id=183&mode=view 에서 스크랩 한 자료입니다.

DataGridColumn을 확장한 DataGrid 개발

 

“Flex

또한 “Flex 애플리케이션 개발에서 클라이언트의 요구가 가장 많이 반영되어야 하는 컴포넌트가 DataGrid 컴포넌트이다. 그러므로 개발자들이 가장 손이 많이 가는 부분이고, 능숙하게 사용할 줄 알아야 하는 것이 DataGrid 컴포넌트라고 생각된다.

그러나 현실적으로 기본적인 DataGrid를 그냥 사용한다면 쓸데 없이 소스코드가 길어지고 가독성이 떨어지게 되어 생산성이 떨어지며 차후 유지보수도 복잡해지게 된다. 고로 본 글에서는 “Flex 애플리케이션 개발에 있어서 DataGridColumn을 확장해 생산성을 높이고 유지보수를 편하게 하는 방법을 제시해볼까 한다.

이 글을 읽는 대상층은  DataGrid를 사용한 경험이 있다는 전제 하에 기본적인 사용법은 생략하고 활용 방법에 대해서만 기술하도록 한다.

 

1.       일반적인 DataGrid 사용하기

A 기업에서, 내부 인사지원 프로그램에 대한 구축 의뢰가 들어왔다. 고객의 요구사항 중에 연봉 컬럼은 3자리마다 ‘,’ 를 찍고 오른쪽 정렬을 해야한다고 명시되어있다. 우리는 일반적으로 아래와 같은 코드를 사용할 것이다. NumberFormatter를 설정하고 labelFunction을 사용해서 값을 변환하고 DataGridColumn textAlign을 이용하여 정렬방법을 세팅할 것이다.

 

<예제코드 1> labelFunction을 사용한 그리드

<mx:Script>

                  <![CDATA[

                                  

                                   private function moneyFormat(item:Object,column:DataGridColumn):String{

                                                     return nf.format(item[column.dataField]);

                                   }                                                                    

                  ]]>

</mx:Script>

 

<mx:NumberFormatter id="nf" useThousandsSeparator="true"/>

 

<mx:DataGrid id="dg" dataProvider="{arr}" width="100%">

                  <mx:columns>

                                   <mx:DataGridColumn headerText="이름" dataField="name"/>

                                   <mx:DataGridColumn headerText="주민번호" dataField="ssn" />

                                   <mx:DataGridColumn headerText="연봉" dataField="salary" labelFunction="moneyFormat" textAlign="right">

                                                     <mx:headerRenderer>

                                                                       <mx:Component>

                                                                                        <mx:Label textAlign="center"/>

                                                                       </mx:Component>

                                                     </mx:headerRenderer>

                                   </mx:DataGridColumn>

                                   <mx:DataGridColumn headerText="입사일" dataField="yyyymmdd"/>

                  </mx:columns>

</mx:DataGrid>

 

일단 연봉 부분만 설정했는데도 소스 부분이 좀 지저분한 느낌이 든다. 여기에 이름, 주민등록번호, 입사일자까지 일일이 포맷을 만들고 labelFunction을 넣어준다면 소스는 더욱 지저분하고 길어질 것이다.

그러므로 LabelFunction 대신 DataGridColumn을 확장하여 format 메쏘드를 통해 미리 설정해 놓은 포맷, 정렬방식으로 표현이 된다면 사용하기가 훨씬 편해질 것이다.

 

2.       DataGridColumn을 확장하기 위한 준비

 

그럼 이제 DataGridColumn을 확장해보자. 먼저 포맷을 만들어준다. 실제 프로젝트에 쓰이는 포맷의 종류는 상당히 많겠지만 가장 일반적으로 쓰이는 금액, 날짜, 주민번호를 만들어보자.

 

<예제코드 2> LabelFormat.as

package comp

{

                  import mx.formatters.NumberFormatter;

                 

                  public class LabelFormat

                  {

                                   public function LabelFormat()

                                   {

 

                                   }

 

                                   // moneyFormat    세자리마다 ',' 찍어준다.

                                   public static function moneyFormat(temp:String,percision:Number):String

                                   {

                                                     var formatter:NumberFormatter = new NumberFormatter();

                                                     formatter.useThousandsSeparator=true;

                                                     formatter.precision = percision;

                                                    

                                                     var result:String = formatter.format(temp);

                                                    

                                                     if(result.charAt(0) == "."){

                                                                       return "0"+result;

                                                     }else if(result.substring(0,2) == "-."){

                                                                       return "-0."+result.substring(2,result.length);

                                                     }else{

                                                                       return result;

                                                     }

                                   }                                                  

 

                                   // dayFormat ,, 구분을 '-' 한다.

                                   public static function dayFormat(temp:String):String

                                   {

                                                     if(temp == "null") return "";

                                                     temp = temp.split("-").join("");

                                                     return temp.substring(0,4)+"-"+

                                                                          temp.substring(4,6)+"-"+

                                                                          temp.substring(6,8)+temp.substring(8,temp.length);

                                   }

                                  

                                   //ssnFormat  주민번호 , 자리를 '-'  구분해준다.

                                   public static function ssnFormat(temp:String):String

                                   {

                                                     temp = temp.split("-").join("");

                                                     if(temp.length == 13){

                                                                       return temp.substring(0,6)+"-"+

                                                                                           temp.substring(6,13);

                                                     }else{

                                                                       return temp;

                                                     }

                                   }

                  }

}

 

이제 LabelFunction을 만든다. LabelFunction이 하는 일은 간단하다. GridColumn의 값을 받아 유효성을 체크하고 LabelFormat에서 지정한 포맷으로 값을 리턴한다.

 

<예제코드 3> LabelFunction.as

package comp

{

                  import mx.controls.dataGridClasses.DataGridColumn;

                  import mx.formatters.DateFormatter;

                 

                  public class LabelFunction

                  {

                                   public function LabelFunction()

                                   {

 

                                   }

                                  

                                   // 금액 labelFormat

                                   public static function moneyFormat(item:Object, column:DataGridColumn):String

                                   {

                                                     if(item[column.dataField] == null) return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                     return LabelFormat.moneyFormat(temp,0);

                                   }               

 

                                   // 날짜 labelFormat

                                   public static function dayFormat(item:Object, column:DataGridColumn):String

                                   {

                                                    

                                                     if(item[column.dataField] == null && item[column.dataField] == "null") return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                    

                                                     // 넘어온 값이 Date 형식이면 dateFormat 이용하여 변환하고

                                                     // String 형이면 위에서 작업한 dayFormat 이용한다.

                                                     if(item[column.dataField] is Date){

                                                                      

                                                                       var dateFormat:DateFormatter = new DateFormatter();

                                                                      

                                                                       dateFormat.formatString="YYYY-MM-DD";

                                                                      

                                                                       return dateFormat.format(item[column.dataField]);

                                                                      

                                                     }else{

                                                                       return LabelFormat.dayFormat(temp);

                                                     }

                                                    

                                   }

 

                                  

                                   // 주민 번호 labelFormat

                                   public static function ssnFormat(item:Object, column:DataGridColumn):String

                                   {

                                                    

                                                     if(item[column.dataField] == null) return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                    

                                                     if(temp.length == 13){

                                                                       return LabelFormat.ssnFormat(temp);

                                                     }else{

                                                                       return temp;

                                                     }

                                   }

 

                                  

                  }

 

 

DataGridColumn에 스타일을 주면 headerText에도 스타일이 적용된다. 그런 것을 방지하기 위하여 HeaderRenderer 작성한다. 보통의 경우 헤더는 센터 정렬이 일반적이므로 옵션 없이 그냥 센터 정렬이 되게 작업하였다.

 

<예제코드 4> HeaderRenderer.as

package comp

{

                  import mx.controls.Label;

 

                  public class HeaderRenderer extends Label

                  {

                                   public function HeaderRenderer()

                                   {

                                                     super();

                                                     this.setStyle("textAlign","center");

                                   }

                                  

                  }

}

 

 

3.       DataGridColumn 확장하기

이제 DataGridColumn 확장하기 위한 준비는 끝났으니 SampleGridColumn을 만들어보자.

DataGridColumn을 상속받아 ConstructorHeaderRenderer 넣어 헤더를 중앙 정렬하게 하고 format 입력 받아 그에 맞는 포맷으로 변경하고 정렬방법을 설정한다. 아래 소스에서는 금액은 오른쪽 정렬, 나머지는 중앙정렬로 설정하였다.

 

<예제코드 5> SampleGridColumn.as

package comp

{

                  import mx.controls.dataGridClasses.DataGridColumn;

                  import mx.core.ClassFactory;

 

                  public class SampleGridColumn extends DataGridColumn

                  {

                                   private var _type:String = "";

                                  

                                  

                                   public function SampleGridColumn(columnName:String=null)

                                   {

                                                     super(columnName);

                                                     this.setStyle("textAlign","center");

                                                    

                                                    

                                                     this.headerRenderer =  new ClassFactory(comp.HeaderRenderer);

                                                    

                                                    

                                   }

 

                                   [Inspectable(defaultValue="money",enumeration="money,ssn,date" )]

                                   public function set format(type:String):void{

                                                    

                                                     _type = type;

                                                    

                                                     switch(type){

                                                                      

                                                                       // 금액일경우 오른쪽 정렬

                                                                       case "money":

                                                                                        this.labelFunction = LabelFunction.moneyFormat;

                                                                                        this.setStyle("textAlign","right");

                                                                                        break;                                      

                                                    

                                                                       // 주민번호일경우 중앙 정렬

                                                                       case "ssn":

                                                                                        this.labelFunction = LabelFunction.ssnFormat;

                                                                                        this.setStyle("textAlign","center");

                                                                                        break;                    

                                                                                       

                                                                       // 날짜일경우 중앙 정렬

                                                                       case "date":

                                                                                        this.labelFunction = LabelFunction.dayFormat;

                                                                                        this.setStyle("textAlign","center");

                                                                                        break;                    

                                                                      

                                                                       // 중앙정렬                                                                                        

                                                                       default:

                                                                                        this.setStyle("textAlign","center");

                                                                      

                                                     }

                                   }

                  }

}

 

위의 소스에서 [Inspectable(defaultValue="money",enumeration="money,ssn,date" )] 부분은 format 메쏘드를 호출할 때 코드 힌트를 설정해주는 부분이다.

 

<그림 1> Inspectable 사용 효과 

 

4.       적용 사례 보기

위의 과정을 통해 컴포넌트를 모두 만들었으니 사용해 보도록 하자.

DataGrid 2개 만들어 위에는 DataGridColumn을 사용하고 아래에는 작업한 SampleGridColumn 을 사용한다. 대신 SampleGridColumn에는 format 메쏘드를 추가하였으므로 포맷에 맞게 값을 세팅한다.

.

<예제코드 6> sample.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" xmlns:comp="comp.*">

 

                  <mx:Script>

                                   <![CDATA[

                                                     import mx.controls.dataGridClasses.DataGridColumn;

                                                     import mx.rpc.events.HeaderEvent;

                                                     [Bindable]

                                                     private var arr:Array = [

                                                                       {name:"홍길동",ssn:"7011111222222",salary:2000,yyyymmdd:"20051214"},                                        {name:"홍길순",ssn:"7111112222322",salary:3000,yyyymmdd:"20040506"},                                        {name:"임꺽정",ssn:"5411111223522",salary:1000,yyyymmdd:"20080102"},                                        {name:"임꺽순",ssn:"2311112224266",salary:6000,yyyymmdd:"19990405"},                                        {name:"일지매",ssn:"3511111222236",salary:8000,yyyymmdd:"20010621"},                                        {name:"김철수",ssn:"7511112228422",salary:9000,yyyymmdd:"19901123"}

                                                     ];

                                                                                       

                                   ]]>

                  </mx:Script>

                 

                  <mx:VBox width="100%">

                                   <mx:DataGrid id="dg" dataProvider="{arr}" width="100%">

                                                     <mx:columns>

                                                                       <mx:DataGridColumn headerText="이름" dataField="name"/>

                                                                       <mx:DataGridColumn headerText="주민번호" dataField="ssn" />

                                                                       <mx:DataGridColumn headerText="연봉" dataField="salary" />

                                                                       <mx:DataGridColumn headerText="입사일" dataField="yyyymmdd"/>

                                                     </mx:columns>

                                   </mx:DataGrid>

 

                                   <mx:DataGrid id="dg2" dataProvider="{arr}" width="100%">

                                                     <mx:columns>

                                                                       <comp:SampleGridColumn headerText="이름" dataField="name" />

                                                                       <comp:SampleGridColumn headerText="주민번호" dataField="ssn" format="ssn"/>

                                                                       <comp:SampleGridColumn headerText="연봉" dataField="salary" format="money"/>

                                                                       <comp:SampleGridColumn headerText="입사일" dataField="yyyymmdd" format="date"/>

                                                     </mx:columns>

                                   </mx:DataGrid>

                                  

                  </mx:VBox>

</mx:Application>

 

 

<그림 2> sample.mxml을 실행한 모습

 

 

위의 DataGrid가 기본 DataGridColumn을 사용한 것이고 아래가 format을 적용시킨 확장된 DataGridColumn이다.

위와 같이 ‘A’ 기업의 인사지원 프로그램 개발 예제를 통해, Flex 애플리케이션 개발에 있어서 DataGridColumn 확장을 통한 DataGrid 개발에 대해서 알아보았다.

이번 예제에서는 기본적인 정보 이름, 주민등록번호, 연봉, 입사일 만 사용했지만, 실제로 프로젝트에서 사용하는 포맷은 요구사항에 따라 훨씬 많아질 것이다. 만약 가계부 프로그램을 개발한다면, 마이너스 잔액은 붉은 텍스트로, 플러스 잔액은 파란 텍스트로 출력되길 원할 것이다. 이러한 것들을 컴포넌트화 하여 간단한 메쏘드의 호출로 제어된다면 작업시간의 단축과 가독성의 증가 효과를 볼 수 있을 것이다.

유지보수 또한 간단해진다. 요구사항 중 이름 필드를 중앙정렬에서 왼쪽정렬로 바꿔달라는 요구가 나온다면 labelFunction.as file의 간단한 수정만으로 모든 프로젝트에 적용된다. 개인적인 생각으로는 컴포넌트의 확장은 프로그램의 개발 생산성에도 많은 도움이 되지만 유지보수시에 더욱 편리하게 사용될 것이다.

마지막으로 본 예제에서의 방법을 숙지하고, 각자가 좀 더 발전시켜 활용해 나간다면, 개발 시간의 단축을 통해 효율을 높이고 완성도를 높임은 물론 유지보수의 편리함도 찾을 수 있을 것이다.

애플리케이션을 개발할 때 가장 많이 사용되는 컴포넌트가 무엇인가?”라고 개발자에게 묻는다면 가장 먼저 나오는 대답은 ‘DataGrid’ 컴포넌트일 것이다. Flex 애플리케이션은 엔터프라이즈 업무용으로 개발이 많이 되기 때문에 특히 데이터 조회를 출력하는 DataGrid 컴포넌트와 Chart 컴포넌트가 가장 많이 사용되고 있다. 간단한 사례로, 일상 업무에서 가장 많이 사용되는 애플리케이션이 엑셀인 것을 생각해 보면 당연한 대답일 것이라고 생각을 할 수 있다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License


티스토리 툴바