자바스크립트/Ext JS2012. 12. 16. 21:18

이전 강좌에서 우리는 좌측 panel안에 davaview를 삽입하여 최초 실행 시 dataview내부 첫번째 data가

선택 되도록 코딩하였습니다.

이번에는 선택 된 데이터뷰가 우측 영역에 어플리케이션으로 나오도록 하고 이 어플리케이션에 그리드와

form을 배치하여 보겠습니다.

우선 컨트롤러가 dataview에서 select한 이벤트를 케치할 수 있도록 아래와 같이 구현합니다.

Ext.define('ria.view.Viewport', {
    extend: 'Ext.container.Viewport',
    layout : 'border',
    items: [
    {
        region: 'center',
        // 기존 panel에서 여러개의 패널을 
        // 붙여야 하므로 tabpanel로 변경합니다.
        xtype: 'tabpanel'
    },{
        region: 'west',
        xtype : 'WestTabPanel',
        width: 200
    }]
});


Ext.define('ria.controller.FrameController', {
.
.
.

   init: function() {
        this.control({
            // step1. 좌측 매뉴에 추가된 패널 즉 시스템 패널에 대한 이벤트 추가.
            'WestMenuPanel > WestMenuDataViewPanel': {
                afterrender: this.firstSelect,
                expand: this.onItemClicked
            }, // select이벤트 잡기.
            'WestMenuDataViewPanel > dataview': {
                select: this.onProgramSelect
            }
         });
    },
    onProgramSelect: function(dataview, record) {
        this.onProgramSelect2(record.get('pgm_class'), record.get('title'));
    },
    /***
     * 최종 클래스명과 탭패널에 추가시 추가할 탭이름을 받는다.
     */
    onProgramSelect2: function(pgm_class, title) {
        var centerpanel =  Ext.ComponentQuery.query('viewport container[region="center"]')[0];
        var tab = centerpanel.down('[tabuniqid=' + pgm_class + title + ']');
        if (!tab) {
            // 아래 클래스를 통해 공통 기능을 구현하고 이 클래스의 item으로 인자로 받아온
            // 클래스를 추가하도록 한다.
            tab = Ext.create('ria.view.pgms.CommonPanel',{
            });
            tab.add(Ext.create(pgm_class,{ region : 'center'}));
            tab.title = title;
            tab.tabuniqid = pgm_class+title;
            centerpanel.add(tab);
        }

        centerpanel.setActiveTab(tab);
    },

위에서 ‘ria.view.pgms.CommonPanel은 모든 프로그램들이 공통적으로 동일한 공통 기능을 갖도록 하기 위해 이 클래스를 부모로 사용하도록 하였다. 이 클래스는 로그아웃, 도움말, 검색 등의 공통적인 기능 가지고 있고 구현해야한다.

Ext.define('ria.view.pgms.CommonPanel',{
    extend : 'Ext.panel.Panel',
    alias : 'widget.CommonPanel',
    layout : 'border',
    initComponent: function() {
        var me = this;

        Ext.apply(this, {
            dockedItems: [{
                xtype: 'toolbar',
                dock: 'top',
                items: [
                    { 
                        xtype: 'button', 
                        text: '도움말',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                console.log('도움말 호출', me.uniqid);
                            }
                        }
                    },'-',
                    { 
                        xtype: 'button', 
                        text: 'MyPage',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                console.log('도움말 호출', me.uniqid);
                            }
                        }
                    },'-',
                    { 
                        xtype: 'button', 
                        text: '로그아웃',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                Ext.Msg.confirm('확인', '로그아웃하시겠습니까?', function(btn) {
                                    if(btn == 'yes') {
                                        console.log('도움말 호출', me.uniqid);
                                        Ext.create('Ext.ux.window.Notification', {
                                            position: 'tr',
                                            useXAxis: true,
                                            cls: 'ux-notification-light',
                                            iconCls: 'ux-notification-icon-information',
                                            closable: false,
                                            title: '확인',
                                            html: '로그아웃되었습니다.',
                                            slideInDuration: 800,
                                            slideBackDuration: 1500,
                                            autoCloseDelay: 4000,
                                            slideInAnimation: 'elasticIn',
                                            slideBackAnimation: 'elasticIn'
                                        }).show();
                                    }
                                });
                            }
                        }
                    },'-',
                    {
                        xtype: 'combo',
                        store: Ext.create('ria.store.system.Programs'),
                        displayField: 'title',
                        typeAhead: false,
                        hideLabel: false,
                        fieldLabel: '검색',
                        labelWidth: 40,
                        hideTrigger:true,
                        width: '400',
                        enableKeyEvents: true,
                        minChars: 2,
                        listConfig: {
                            loadingText: '검색 중입니다....',
                            emptyText: '검색어에 맞는 검색 결과가 없습니다.',

                            // Custom rendering template for each item
                            getInnerTpl: function() {
                                return '< h3 >< span >{[Ext.Date.format(values.input_date, "M j, Y")]}< br />by {input_user_name}< /span >{title}< /h3 >' +
                                    '{excerpt}';
                            }
                        },
                        pageSize: 10,
                        listeners: {
                            select: function(a, b) {
                                console.log(a,b)
                            }

                        }

                    }
                ]
            }]
        });
        me.callParent(arguments);
    }
});
이제 위의 CommonPanel안에 들어갈 즉 선택 되어 보여줘야할 어플리케이션을 구현해 보겠습니다.
위의 코드대로 실행하면 에러가 발생할 것입니다. 우선 아래의 json파일을 보겠습니다.
아래 파일은 dataview에 보여지고 있는 프로그램 리스트입니다. 그 중 첫번째 라인을 아래 소스와 같이 
수정합니다.
ria.view.pgms.project.ProjectMgrPanel은 우리가 구현할 프로그램으로 사내 프로젝트를 심플하게 관리하는
프로그램입니다.
/**
 ** Date : 2012.11.30
 ** Desc : 시스템이하 프로그램 리스트 제공
 ** Posn : /json/programlist.json
 **/
{"entitys":[{"pgm_class":"ria.view.pgms.project.ProjectMgrPanel","pgm_icon":"grid","pgm_nm":"나의 과제","title":"나의 과제"},
            {"pgm_class":"ria.view.pgms.RiaAppMain02","pgm_icon":"grid","pgm_nm":"하위 프로그램2","title":"프로그램2"},
            {"pgm_class":"ria.view.pgms.RiaAppMain03","pgm_icon":"grid","pgm_nm":"하위 프로그램3","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain04","pgm_icon":"grid","pgm_nm":"하위 프로그램4","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain05","pgm_icon":"grid","pgm_nm":"하위 프로그램5","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain06","pgm_icon":"grid","pgm_nm":"하위 프로그램6","title":"커뮤니케이션팀"}
            ],
            "errMsg":"","errTitle":"검색결과","message":"","success":true,"totalCount":"2"}



// ria.view.pgms.project.ProjectMgrPanel 구현 하기.
Ext.define('ria.view.pgms.project.ProjectMgrPanel',{
    extend : 'Ext.panel.Panel',
    alias : 'widget.ProjectMgrPanel',
    layout : 'border',
    initComponent: function() {
        var me = this;
        this.callParent(arguments);
    }
});

이제 실행해보면 아래와 같은 모양의 프로그램이 우측 패널에 보여지게 된다.

공통적으로 도움말, MyPage,로그아웃, 검색 등의 기능을 사용할 수 있는 구조이다.

각각의 기능은 나중에 구현하도록 하고 “나의과제”라는 프로그램을 구현해봅니다.

이 프로그램은 좌측에 그리드패널을 그 그리드의 데이터를 select하면 우측의 폼패널이 열리고

해당 과제의 내용을 보여주도록 구현하겠습니다.

/**
 ** Date : 2012.11.30
 ** Desc : 프로젝트 리스트 제공
 ** Posn : /json/projectlist.json
 **/
{"entitys":[{"prj_master_no":"PJ000001","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000002","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000003","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000004","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000005","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000006","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000007","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000008","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"}
            ],
            "errMsg":"","errTitle":"검색결과","message":"","success":true,"totalCount":"340"}
/**
 * Date : 2012.11.30
 * Desc : 프로젝트 정보를 표현할 모델 클래스
 */
Ext.define('ria.model.ProjectMaster', {
    extend: 'Ext.data.Model',   // extend
    fields: [
        'prj_master_no',
        'ytree_sgy_dtl_seq',
        'prj_leader',
        'prj_name',
        'prj_bgrnd',
        'prj_target',
        'prj_effect',
        'prj_status_cd',
        'prj_status_nm',
        'prj_std_dt',
        'prj_end_dt',
        'input_user_name',
        'input_user_id',
        'input_date'
    ]
});

/**
 * Date : 2012.12.14
 * Desc : 프로젝트 리스트
 */
Ext.define('ria.store.project.Projects', {
    extend: 'Ext.data.Store',   // 당연히 store상속
    autoLoad : false,           // 자동 로드는 꺼놓자.
    model: 'ria.model.ProjectMaster',   // 모델은 동일하게 사용 세팅
    proxy: {
        type: 'ajax',
        url: '/json/project/projectlist.json',  
        reader: {
            type: 'json',
            root: 'entitys',
            totalProperty: 'totalCount',
            messageProperty: 'message'
        },
        listeners: {
            exception: function(proxy, response, operation){
                // 나중에 구현할 부분 모든 ajax 통신에 공통으로 쓸 수 있는
                // 에러 캐치 함수를 만들 것이다.
            }
        }
    }
});

Ext.define('ria.view.pgms.project.ProjectListPanel',{
    extend : 'Ext.grid.Panel',
    alias  : 'widget.ProjectListPanel',
    columnLines: true,
    initComponent: function() {
        var me = this;
        var store = Ext.create('ria.store.project.Projects');
        Ext.apply(this, {
            store: store,
            columns: [
            {
                text: '과제번호',
                width : 80,
                dataIndex: 'prj_master_no'
            },
            {
                text: '제목',
                flex : 1,
                dataIndex: 'prj_name'
            },
            { 
                text: '작성자',
                width: 70,
                sortable: false,
                dataIndex: 'input_user_name'
            },
            { 
                text: '시작일',
                width: 70,
                sortable: false,
                dataIndex: 'prj_std_dt'
            },
            { 
                text: '종료일',
                width: 70,
                sortable: false,
                dataIndex: 'prj_end_dt'
            },
            { 
                text: '작성일',
                width: 70,
                sortable: false,
                dataIndex: 'input_date'
            }],
            dockedItems: [
            {
                xtype: 'pagingtoolbar',
                store: store,
                //name : 'fnc003Main01',
                dock: 'bottom',
                displayInfo: true
            }],
            boardLoad : function(){
                me.store.load({             // 아직 로드전이므로 로드한다.이때 json파일 호출
                    params : {
                        km : 'A00000001'
                    }
                });
                //console.log('me.store:::', me.store)
            }
        });
        me.callParent(arguments);
        this.on('render', this.boardLoad, this);
    }
});

Ext.define('ria.view.pgms.project.ProjectMgrPanel',{
        extend : 'Ext.panel.Panel',
        alias : 'widget.ProjectMgrPanel',
        layout : 'border',
        initComponent: function() {
                var me = this;
                Ext.apply(this, {
                        items : [{
                                xtype : 'ProjectListPanel',
                                title : '과제리스트',
                                region: 'center'
                        }]
                });
                this.callParent(arguments);
        }
});

이제 실행해 봅니다. 우측에 프로젝트 리스트 패널이 실행되고 json파일의 내용이 출력되는 것을
확인 할 수 있습니다.

Posted by 1 베니94

댓글을 달아 주세요

  1. ExtJS 초보

    Benney님 작성하신 강좌를 처음부터 따라해보고 있는 초보입니다.
    ria.controller.FrameController 소스 내용 중 centerpanel.setActiveTab(tab); 에서 error가 발생해서 이것저것 삽질하던 중에 이전 강좌에서 ria.view.Viewport의 내용중에 아래와 같이 수정하니 정상동작하는 듯하여 제가 수정한 것이 맞는지 문의드립니다. ^^

    Ext.define('ria.view.Viewport', {
    extend: 'Ext.container.Viewport',
    layout : 'border',
    items: [
    {
    region: 'center',
    xtype: 'tabpanel' <-- 이전강좌에는는 'panel'로 되어 있음.
    <-- title: '중간' 삭제
    },{
    region: 'west',
    xtype : 'WestMenuPanel',
    width: 200
    }]
    });

    친절한 강좌 감사드려요 ^^

    2012.12.18 16:43 [ ADDR : EDIT/ DEL : REPLY ]
    • 아 제가 그부분을 설명 안들렸나보군요.
      처음에는 panel을 사용해서 하나의 프로그램만 띄울수
      있게 했으나 이후에 tabpanel로 변경해서 여러개의 프로그램을
      띄울수 있게 수정했습니다.
      지적하신 부분이 맞습니다. 내용을 좀 수정하도록 하겠습니다.
      감사합니다.^^

      2012.12.19 12:40 신고 [ ADDR : EDIT/ DEL ]
  2. 초보ExtJs

    안녕하세요
    ~ 강좌진행은 계속되시는건가요,.,^^;;
    기다리고있겠습니다.

    2013.01.15 18:23 [ ADDR : EDIT/ DEL : REPLY ]
    • benneykwag@gmail.com

      네 계속하죠 근데 강좌가 중간에 짤렸네요.
      이상합니다. 복구하겠습니다. ㅠㅠ

      가끔 이렇게 리플달아주신 분들이 계셔서
      힘이 납니다.
      직딩이 강좌하는게 이리 어려운건지
      때려치우고 강사나 했으면 좋겠습니다. ㅋㅋ

      2013.01.17 09:24 [ ADDR : EDIT/ DEL ]
  3. 리핀

    안녕하세요 ~
    저역시 배니님의 강좌를 기대하고 있습니다 ~~^^
    화이팅~ 항상 알찬 내용 감사합니다..~
    더불어 질문이 하나 있는데..
    저 같은 경우 xtype : 'WestMenuPanel' 을 'WestTabPanel' 로 변경할 경우
    ext-debug.js 에서 undefined 에러가 나는데.. ext-debug를 호출하는 시점이 언제쯤인지 궁금하여 연락드립니다.

    2013.01.15 18:49 [ ADDR : EDIT/ DEL : REPLY ]
    • 컨트롤러에 WestTabPanel이 명시되어있어야 합니다.
      Ext.define('ria.controller.FrameController', {
      .
      .
      views: ['ria.view.frame.WestMenuPanel',
      'ria.view.frame.WestMenuDataViewPanel',
      'ria.view.frame.WestTabPanel'], // 꼭 명시되어야함, 명시하지 않을 경우 require를 이용해야합.

      감사합니다. ^^

      2013.01.17 10:15 신고 [ ADDR : EDIT/ DEL ]
  4. 초보초보extjs

    안녕하세요.
    시간이 되신다면 서버단 관련해서 샘플 자료 하나 올려주실수 없으신가요.^^;;
    맨땅에 헤딩하려니 너무 힘드네요..ㅠㅠ
    강좌 잘보고 있습니다.

    2013.08.20 18:01 [ ADDR : EDIT/ DEL : REPLY ]