Extjs를 설치했다면 이제 sample등을 잘 활용하여 사용하기만 하면 된다.
ExtJs를 사용하기 위해서는 ExtJs의 기본 구조를 잘 이해해야 한다.
ExtJs는 Client Side Script인 javascript로 이루어진 Web 개발 library이다. 이 library가 공통으로 화면에 로딩되고 그 상태에서 사용자가 작성한 화면 script가 실행되는 형식이다. Sencha에서 제안하는 또 다른 방법은 extjs를 활용하여 화면 구성에 필요한 새로운 library를 생성하여 이를 배포하는 방식이다. script프로그램의 특성상 화면의 로딩 속도가 빨라야 하고 화면에 표시되는 부분(View)와 데이터를 처리하는 부분(Model)을 분리하여 코드의 재가용성도 높일수 있는 방법이다(MVC Model).
그러나 소규모의 개발에서는 오히려 사용이 어렵고 코드의 재가용성에 대한 요구가 높지 않은 경우 불필요한 작업까지 포함될 수 있고, 소스가 짧은 경우 로딩속도가(script언어의 특성상 개발시 포함된 space와 tab 문자들이 모두 소스에 포함되어 있어 파일 크기가 커진다) 크게 차이나지 않기 때문에 간단히 script-engine + script 방식으로 구성해도 충분한 것 같다.
사실 대부분의 web browser는 javascript(또는 vbscript)를 분석(compile)하고 실행하기 위한 엔진(gecko와 같은 레이아웃 엔진내에)을 탑재하고 있다. 여기에 낮은 레벨의 javascript와 style-sheet를 결합하여 매크로처럼 화면 구성용 함수들을 만들어 놓은 library가 ExtJs이므로 이를 그냥 가져다가 쉽게 사용하기만 하면 되니, 복잡하게 새로운 개발이나 대단위 프로젝트는 생각하지 않기로 했다.
대신 화면 개발시 유사한 화면에 반복적으로 포함되는 코딩을 조금 더 쉽게 처리하기 위한 방법을 고민하다 보니 오히려 Server side의 library가 더 적합하다는 생각을 하게 되었다.

우선 무작정 하드코딩으로 ExtJs를 이용한 page를 개발하기 위해서는 extjs library를 서버에 설치하고 이를 각 page가 로딩될 때 같이 로딩될 수 있도록 한다.

<meta http-equiv="X-UA-Compatible" content="IE=7"> <title>F-square</title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta http-equiv="expires" content="0" /> 
<meta http-equiv="Cache-control" content="no-cache" /> 
<meta http-equiv="Cache-control" content="max-age=0" /> 
<meta http-equiv="pragma" content="no-cache" />
<!-- 적용된 테마 외에 추가적인 style정의를 모아 놓은 sheet -->
<link rel="stylesheet" type="text/css" href="./design/css/menu_blue.css" media="screen" />

<!-- extjs 핵심 library -->
<script type="text/javascript" src="./js/include-ext.js"></script> 

<script type="text/javascript" src="./js/options-toolbar.js"></script>

<script type="text/javascript" src="./js/lib.js"></script>

디렉토리 구조는 각자가 설치하기 나름이므로 설치된 경로를 그대로 써 주면되겠다.
먼저 첫번째에 meta로 잔뜩 나오는 부분은 주로 web browser의 cache를 지워주기 위한 부분이다. 각 페이지 내용을 web browser가 cache(PC상에 임시저장)하고 있으면 개발 작업시 변경부분이 적용되지 않아 혼란을 줄 수 있다. 따라서 가급적 cache는 지워버리도록 하는 것이 좋다. 반대의 경우 static한 내용을 반복적으로 보여줘야 할 때는 cache되어 있는 것이 속도 면에서는 훨씬 유리하다.

이제 본격적으로 코딩을 시작해 보자.
ExtJs설치시 포함되어 있는 예제 파일을 하나씩 소스에 추가해서 실행시켜 보면서 그 구조를 파악하면 훨씬 쉽게 이해할 수 있다.

여기서는 FeedViewer Demo와 Tree, Tab을 이용하여 화면을 구성하고 내부 화면은 iframe으로 간단히 정보조회 화면을 구성하도록 하였다.
편집기는 Text Editor와 vi를 혼용하였고, 테스트는 Web brower로 직접 화면을 보면서 수정을 하였다(Subscription가입을 하지 않아 UI-Designer를 구하지는 못했다).

<script type="text/javascript">

Ext.onReady(function() {
    Ext.QuickTips.init();
    var viewport = Ext.create('Ext.Viewport', {
    id: 'border-example',
    layout: 'border',
    items: [
        // create instance immediately
        Ext.create('Ext.Component', {
            region: 'north',      // 화면의 북쪽(윗쪽)에 위치
            height: 58, // give north and south regions a height 
            autoEl: {
                tag: 'div'
            }
        }), {

            // lazily created panel (xtype:'panel' is default)
            region: 'south',  // 화면의 남쪽(아랫쪽)에 위치하는 panel
            contentEl: 'south', // div id='south'라고 하는 content를 overriding함
            split: true,  // 크기조정이 가능한 split
            height: 70,
            minSize: 100,
            maxSize: 200,
            collapsible: true,
            collapsed: true,
            title: 'Ticker',
            margins: '0 0 0 0'
        },

        {
            region: 'west',            // 화면의 서쪽(왼쪽)에 위치
            stateId: 'navigation-panel',
            id: 'west-panel', // see Ext.getCmp() below
            title: 'Menu',
            split: true,  // 크기조정이 가능한 split
            width: 200,
            minWidth: 175,
            maxWidth: 400,
            collapsible: true,  // 닫힘 기능이 가능
            animCollapse: true,  // 닫힐때 애니메이션 적용
            margins: '0 0 0 5',
            layout: 'accordion',  // accordion layout으로 탭들이 존재
            items: [{             // accordion layout으로 존재하는 탭의 아이템들
                    title: '즐겨찾기',
                    xtype: 'treepanel',             //  tree panel object 생성
                    id: 'favorit',
                    iconCls: 'nav',                 // style로 정의된 'nav' icon
                    margins: '2 2 0 2',
                    autoScroll: true,
                    rootVisible: false,
                    root: { text: "Root Node",      // tree의 node의 정의
                        children:[
                            {text:'메뉴1', id: 'PMS_0001', leaf:true},   // 각각의 메뉴
                            {text:'메뉴100', id: 'PMS_0100', leaf:true}
                        ]
                    },

                    listeners: {
                        itemclick : function(s,d){                // tree menu를 click 했을때의 action
                            if ( d.data.leaf ) {
                                var scr_id = "S" + d.data.id;
                                var scr_title = d.data.text;
                                var scr_filename = "PMS/SG" + d.data.id.trim() + "_SUB.php?theme=neptune";    // PMS디렉토리 내에있는 php파일명 생성
                                var tab = Ext.getCmp( scr_id );
                                var mainPanel = Ext.getCmp('MainPanel');
                                if ( tab != null ) {
                                    mainPanel.setActiveTab(tab);  // 만약 이미 화면이 열려있으면 해당 화면을 activate시킴
                                }
                                else {
                                    var tab = new Ext.Panel({      // 새로운 창에 화면을 open
                                        id: scr_id,
                                        title: scr_title,
                                        closable:true,
                                        autoScroll: false,
                                        border:false,
                                        layout:'fit',
                                        frame: false,
                                        html: '<iframe src="' + scr_filename + '" frameborder="no" allowtransparency="y" vspace="0" hspace="0" width="100%" height="100%"></iframe>'  // iframe으로 tab 내에서 화면을 open함
                                    });

                                    mainPanel.add(tab);
                                    mainPanel.setActiveTab(tab);  // tab을 add하고 activate함
                                }
                            } // if ( d.data.leaf ) 의 끝
                        } // itemclick : function(s,d)의 끝
                    } // listener의 끝
                    }, {
                        title: '자금관리',
                        xtype: 'treepanel',
                        id: 'Fund-manager',
                        iconCls: 'info',
                        margins: '2 2 0 2',
                        autoScroll: true,
                        rootVisible: false,
                        root: { text: "Root Node",
                            children:[
                                { text: '<b>메뉴1</b>', id: 'PMS_0001', leaf:true},
                                { text: '<b>메뉴2</b>', id: 'PMS_0002', leaf:true},
                                { text: '<b>메뉴100</b>', id: 'PMS_0100', leaf:true},
                                { text: '<b>메뉴200</b>', id: 'PMS_0200', leaf:true}
                            ]
                        },

                        listeners: {
                        itemclick : function(s,d){
                            if ( d.data.leaf ) {
                                var scr_id = "S" + d.data.id;
                                var scr_title = d.data.text;
                                var scr_filename = "PMS/SG" + d.data.id.trim() + "_SUB.php?theme=neptune";
                                var tab = Ext.getCmp( scr_id );
                                var mainPanel = Ext.getCmp('MainPanel');
                                if ( tab != null ) {
                                    mainPanel.setActiveTab(tab);
                                }
                                else {
                                    var tab = new Ext.Panel({
                                        id: scr_id,
                                        title: scr_title,
                                        closable:true,
                                        autoScroll: false,
                                        border:false,
                                        layout:'fit',
                                        frame: false,
                                        html: '<iframe src="' + scr_filename + '" frameborder="no" allowtransparency="y" vspace="0" hspace="0" width="100%" height="100%"></iframe>'
                                    });

                                    mainPanel.add(tab);
                                    mainPanel.setActiveTab(tab);
                                }
                            } // if ( d.data.leaf ) 의 끝
                        } // itemclick : function(s,d)의 끝
                    } // listener의 끝
                    }, {
                        title: '환경설정',
                        xtype: 'treepanel',
                        id: 'tree-config',
                        iconCls: 'settings',
                        margins: '2 2 0 2',
                        autoScroll: true,
                        rootVisible: false,
                        root: { text: "Root Node",
                            children:[
                                {text:'즐겨찾기 설정', id: 'CFG_1000', leaf:true},
                                {text:'화면 설정', id: 'CFG_2000', leaf:true}
                            ]
                        },

                        listeners: {
                            itemclick : function(s,d){
                                if ( d.data.leaf ) {
                                    var scr_id = "S" + d.data.id;
                                    var scr_title = d.data.text;
                                    var scr_filename = "CFG/S" + d.data.id.trim() + ".php?theme=neptune";
                                    var tab = Ext.getCmp( scr_id );
                                    var mainPanel = Ext.getCmp('MainPanel');
                                    if ( tab != null ) {
                                        mainPanel.setActiveTab(tab);
                                }
                                else {
                                    var tab = new Ext.Panel({
                                        id: scr_id,
                                        title: scr_title,
                                        closable:true,
                                        autoScroll: false,
                                        border:false,
                                        layout:'fit',
                                        frame: false,
                                        html: '<iframe src="' + scr_filename + '" frameborder="no" allowtransparency="y" vspace="0" hspace="0" width="100%" height="100%"></iframe>'
                                    });

                                    mainPanel.add(tab);
                                    mainPanel.setActiveTab(tab);
                                }
                            }
                        }
                    }
                }
            ]
        },

        Ext.create('Ext.tab.Panel', {   // 화면의 가운데 tab panel생성 (mainpanel이라고 명명)
            region: 'center', // a center region is ALWAYS required for border layout
            deferredRender: false,
            bodyStyle: 'background-size:contain; background-image:url(http://www.nyewall.com/images/2013/07/background-flowers-sky-wallpaper-blue-nice-wallpapers.jpg);',
            id: 'MainPanel',
            activeTab: 0 // first tab initially active
        })]
    });

    // get a reference to the HTML element with id "hideit" and add a click listener to it
    Ext.get("hide-it").on('click', function(){
        var w = Ext.getCmp('west-panel');
        w.collapsed ? w.expand() : w.collapse();
    });
});
</script>

<body bgcolor="#F0F0FF" /* onload=reqeustFullScreen();*/>
<table width=100% border=0 cellpadding=0 cellspacing=0 >
<tr><td align=left width=145 class="logo">AMS</td><td align=left class="logo"></td></tr>
<tr><td align=left width=145 class="logo_under">&nbsp; Management System</td><td class="logo_under">- AMS Consulting</td></tr>
</table>

<!-- use class="x-hide-display" to prevent a brief flicker of the content -->
<div id="west" class="x-hide-display">
<p>west panel</p>
</div>
<div id="center2" class="x-hide-display">
<a id="hide-it" href="#"> </div>
<div id="center1" class="x-hide-display">
</div>
</div>
<div id="south" class="x-hide-display">
<p>정상상태</p>
</div>
<br/>

이제 해당 library와 style sheet가 적절한 경로에 설치만 되어 있다면 첫번째 메인 화면이 정상적으로 뜰 것이다.
fundratings
이제 메인화면을 생성했고 앞으로 해야할 파일은 각 메뉴를 클릭했을 때 iframe상에 뜰 각각의 화면 파일을 생성하는 일만 남았다.
그런데 메인화면을 자세히 보면 반복적인 부분들이 보일것이다. 즉, tree menu가 즐겨찾기, 화면메뉴, 환경설정 등과 같이 동일한 형태의 자료구조로 반복되는 것을 볼 수 있는데 이러한 부분을 모두 Hard coding으로 fix하지 말고 서버측에서 동적으로 DB를 조회하여 생성하면 반복작업이 훨씬 줄어들 것이다.

index.php
<header>
...
<script type="text/javascript">

...
<?         include 'lib/db.php';
         // db 조회시작
         ....
         // 조회 결과를 출력
         ...
         while ( $rs = mssql.next() ) {                   if ($row_cnt > 0 ) echo ",\n";
                  echo "{ text : '" . $rs.getString(1) . "', id : " . $rs.getString(2) . ", leaf : " . $rs.getString(5) . "}";
                  $row_cnt ++;
      }

?>
     }
   ]

By yaplab

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다